본문 바로가기

C 프로젝트/리눅스 프로그래밍

C 라이브러리 - 패턴 매칭


1. 정규식 매칭


GNU C 라이브러리는 정규식을 매치하기 위한 두 개의 인터페이스를 제공한다.

하나는 POSIX2 인터페이스이고 다른 하나는 GNU 시스템이 오랫동안 가지고 있었던 것이다

두개의 인터페이스는 헤더파일 "regex.h"에 선언되어 있다.


데이터 타입 : regex_t

이것은 컴파일된 정규식을 저장하는 오브젝트 타입이다. 그것은 실제로 구조체이다.


int regcomp (regex_t *compiled, const char *pattern, int cflags)

regcomp 함수는 문자열과 매치시키는데 사용하는 regexec를 사용할 수 있도록 정규식을 데이터 구조체로 "컴파일"한다. 컴파일된 정규식의 형식은 매칭(matching)에 효율적이게 만들어졌다. regcomp는 *compiled에 그것을 저장한다.

regcomp는 정규식을 컴파일하는데 성공하면 0을 반환하고; 그렇지 않으면 0이 아닌 에러코드( 밑에 설명된 )를 반환한다

REG_BADBR

정규식안에 유용하지 않은 `\{. . . \}` 구성이 있었다. 유용한 `\{. . . }\` 구성은 단일한 숫자, 또는 콤마로 분리된 오름차순으로 된 두 개의 숫자 중 하나를 포함해야만 한다.

REG_BADPAT

정규식에 구문에러가 있었다.

REG_BADRPT

`?'나 `*'와 같은 반복 연산자가 나쁜 위치에 있다(선행하는 아무런 부표현식도 없이 ).

REG_ECOLLATE

정규식이 유용하지 않은 대조(collating) 요소를 참조하였다. (문자열 대조를 위해서 현재의 지역에서 정의되지 않은 것. ) 

REG_ECTYPE

정규식이 유용하지 않은 클래스 이름을 참조하였다.

REG_EESCAPE

정규식이 `\' 으로 끝났다.

REG_ESUBREG

`\digit' 구성에 유용하지 않은 숫자가 있었다.

REG_EBRACK

정규식 안에 균형이 맞지 않는 sqrare brackets([, ])가 있었다.

REG_EPAREN

연장된 정규식이 균형이 맞지 않는 괄호를 갖었거나, 기본 정규식이 균형이 맞지 않는 `\(' 와 `\)'를 가졌다.

REG_EBRACE

정규식이 균형이 맞지 않는 `\{' 와 `\}'을 가졌다.

REG_ERANGE

범위 표현식에서 끝점의 하나가 유용하지 않다.

REG_ESPACE

regcomp가 메모리를 다 써버렸다.

* POSIX 정규식을 위한 플래그

REG_EXTENDED

기본 정규식이 아닌, 연장된 정규식으로 패턴을 취급하라.

REG_ICASE

문자들을 매치할 때 대, 소문자 구분을 무시하라.

REG_NOSUB

match_ptr 배열에 저장한 내용들을 건드리지 말아라.

REG_NEWLINE

문 자열에 있는 새줄문자를 여러 개의 라인으로 문자열을 나누는 역할을 하는 것처럼 취급한다, 그래서 `$'은 새줄문자 전에 매치할 수 있고, `^'은 새줄문자 후에 매치할 수 있다. 또한, 새줄문자와 매치하기 위해 `. '을 허용하지 않고, `[^. . . ]'을 허용하지 않는다. 그렇지 않다면 새줄문자는 다른 보통의 문자들처럼 작용한다.



함수 : int regexec(regex_t *compiled, char *string, size_t nmatch, regmatch_t matchptr [], int eflags)

이 함수는 문자열을 컴파일된 정규식*compiled와 매치하려 시도한다. regexec 는 만일 정규식이 매치되면 0을 반환하고; 그렇지 않다면 0이 아닌 값을 반환한다. 0이 아닌 값들이 무엇을 의미하는지 밑 테이블에 설명해 놓았다.

regexec가 반환할 수 있는 0이 아닌 값들에 대한 설명.

    REG_NOMATCH

    패턴이 문자열과 매치되는 것이 없다. 이것은 사실상 에러는 아니다.

    REG_ESPACE

    regexec가 메모리를 다 써버렸다.

regexec 함수가 패턴의 괄호로 묶인 부문자열을 매치할 때, 그것은 매치하려는 문자열의 부분들을 기록한다. 그것은 구조체 regmatch_t 형인 요소를 가진 배열 안의 offsets 에 저장하여 그 정보를 반환한다. 그 배열(index 0)의 첫 번째 요소는 전체 정규식과 매치된 문자열의 부분을 기록한다. 배열의 다른 요소들은 단 하나의 괄호로 묶인 부표현식과 매치된 부분의 처음과 끝을 기록한다.


데이터타입 : regmatch__t

이것은 당신이 regexec 함수에서 사용하기 위한 배열 matcharray의 데이터타입이다. 그것은 다음과 같은 두 개의 필드들을 갖고 있다.
rm_so 문자열에 있는 부문자열의 시작점의 offset. 그 부분의 주소를 얻기 위하여 문자열에 이 값을 더하라.
rm_eo 문자열에 있는 부문자열의 끝점의 offset

데이터타입 : regoff__t

regoff_t 는 signed integer 형의 다른 이름이다. regmatch_t의 필드들은 regoff_t의 형을 갖는다. regmatch_t 요소들은 부표현식의 위치에 대한 것이다; 첫 번째 요소( index 1)는 매치된 첫 번째 부표현식이 어디에 있는지를 기록하고, 두 번째 요소는 두 번째 부표현식을 기록하고, 등등. 부표현식의 순서는 그들이 나타난 순서이다.

컴파일된 정규식을 다 사용했을 때, 당신은 regfree를 사용해서 그 저장공간을 해제할 수 있다.

함수: void regfree (regex_t *compiled)

regfree 를 호출해서 *compiled가 가리키고 있는 모든 저장영역을 해제할 수 있다. 이것은 이 매뉴얼에서는 설명하지 않았지만, 구조체 regex_t의 다양한 내부적 필드들을 포함하고 있다. regfree는 오브젝트 *compiled 자체를 해제하지 않는다.

당 신은 다른 정규식을 컴파일하기 위해 그 구조체를 사용하기 전에 regfree를 사용해서 구조체 regex_t 안에 있는 공간을 항상 해제해야한다. regcomp나 regexec에서 에러가 났을 때, 당신은 에러메시지를 출력하기 위해서 regerror함수를 사용할 수 있다.


함수: size_t regerror (int errcode, regex_t *compiled, char *buffer, size_t length)

이 함수는 에러코드 errcode를 위한 에러메시지 문자열을 생성하고, buffer에서 시작하는 메모리의 length 바이트 안에 그 문자열을 저장한다. 컴파일된 인수를 위해서, regcomp나 regexec에서 작업되었던 같은 컴파일된 정규식 구조체를 공급한다. 선택적으로, 당신은 compiled를 위해서 NULL을 공급할 수 있다; 당신은 여전히 의미 있는 에러메시지를 얻을 것이다, 그렇지만, 그것은 상세하지 않을 것이다.

만일 그 에러메시지가 length 바이트의 길이에 맞을 수 없다면(널 종료문자를 포함해서), 그러면 regerror는 그것은 자른다. regerror 이 저장한 문자열은 심지어 그것이 잘렸을 때라도 널 종료문자를 저장한다. regerror의 반환값은 전체 에러메시지를 저장하기 위해 필요한 최소 길이이다. 만일 이것이 length보다 적다면, 에러메시지는 잘리지 않고, 당신은 그것을 사용할 수 있다. 그렇지 않다면, 당신은 더큰 버퍼를 잡아서 다시 regerror를 호출해야한다. 이곳에 regerror를 사용하는 함수가 있는데, 에러메시지를 위한 버퍼를 항상 동적으로 할당한다.
char *get_regerror (int errcode, regex_t *compiled)
{
size_t length = regerror (errcode, compiled, NULL, 0);
char *buffer = xmalloc (length);
(void) regerror (errcode, compiled, buffer, length);
return buffer;
}

출처 : http://unabated.tistory.com/entry/%ED%8C%A8%ED%84%B4-%EB%A7%A4%EC%B9%AD-Pattern-Matching

'C 프로젝트 > 리눅스 프로그래밍' 카테고리의 다른 글

Thread Safe  (0) 2014.05.23
epoll  (0) 2014.05.22
Socket Non-blocking  (0) 2014.05.22
C 라이브러리 - 패턴 매칭 사용 예제  (0) 2014.04.04
조건 변수 , 뮤텍스  (0) 2013.12.26