2009-09-14 4 views
5

C를 사용하는 데 익숙하지 않으며 PCRE를 사용하여 일치해야합니다.
다음 내 소스 코드의 샘플입니다 :이 데모에서PCRE를 사용하여 모든 성냥 그룹을 얻으려면 어떻게해야합니까?

int test2() 
{ 
    const char *error; 
    int erroffset; 
    pcre *re; 
    int rc; 
    int i; 
    int ovector[OVECCOUNT]; 

    char *regex = "From:([^@]+)@([^\r]+)"; 
    char str[] = "From:[email protected]\r\n"\ 
        "From:[email protected]\r\n"\ 
        "From:[email protected]\r\n"; 

    re = pcre_compile (
      regex,  /* the pattern */ 
      0,     /* default options */ 
      &error,    /* for error message */ 
      &erroffset,   /* for error offset */ 
      0);     /* use default character tables */ 

    if (!re) { 
     printf("pcre_compile failed (offset: %d), %s\n", erroffset, error); 
     return -1; 
    } 

    rc = pcre_exec (
     re,     /* the compiled pattern */ 
     0,     /* no extra data - pattern was not studied */ 
     str,     /* the string to match */ 
     strlen(str),   /* the length of the string */ 
     0,     /* start at offset 0 in the subject */ 
     0,     /* default options */ 
     ovector,    /* output vector for substring information */ 
     OVECCOUNT);   /* number of elements in the output vector */ 

    if (rc < 0) { 
     switch (rc) { 
      case PCRE_ERROR_NOMATCH: 
       printf("String didn't match"); 
       break; 

      default: 
       printf("Error while matching: %d\n", rc); 
       break; 
     } 
     free(re); 
     return -1; 
    } 

    for (i = 0; i < rc; i++) { 
     printf("%2d: %.*s\n", i, ovector[2*i+1] - ovector[2*i], str + ovector[2*i]); 
    } 
} 

의 출력은 다음과 같습니다

0: From:[email protected]
1: regular.expressions
2: example.com

내가 출력에 모두를 원하는 성냥; 내가 어떻게 할 수 있니?

+0

정규 표현식을 사용하지 말고 실제 파서를 사용하십시오. mail protocoal은 일반 우편함 주소 그 이상을 허용합니다. – Gumbo

+0

이것은 pcre의 데모이며, 그룹 일치에 pcre를 사용하는 방법을 알고 싶습니다. 의견을 보내 주셔서 감사합니다. – tbmvp

+0

이 게시물을 참조해야합니다 : http://stackoverflow.com/questions/7785557/pcre-match-all-groups-in-c – soulmachine

답변

6

나는 이것을 쉽게하기 위해 PCRE를 래핑하기 위해 클래스를 사용하지만, pcre_exec 뒤에는 원래 문자열 내에서 일치하는 것을 찾으려면 부분 문자열 인덱스가 포함됩니다.

는 그래서 것 같은 뭔가 :

#include <string> 
#include <iostream> 
#include "pcre.h" 

int main (int argc, char *argv[]) 
{ 
    const char *error; 
    int erroffset; 
    pcre *re; 
    int rc; 
    int i; 
    int ovector[100]; 

    char *regex = "From:([^@]+)@([^\r]+)"; 
    char str[] = "From:[email protected]\r\n"\ 
        "From:[email protected]\r\n"\ 
        "From:[email protected]\r\n"; 

    re = pcre_compile (regex,   /* the pattern */ 
         PCRE_MULTILINE, 
         &error,   /* for error message */ 
         &erroffset,  /* for error offset */ 
         0);    /* use default character tables */ 
    if (!re) 
    { 
     printf("pcre_compile failed (offset: %d), %s\n", erroffset, error); 
     return -1; 
    } 

    unsigned int offset = 0; 
    unsigned int len = strlen(str); 
    while (offset < len && (rc = pcre_exec(re, 0, str, len, offset, 0, ovector, sizeof(ovector))) >= 0) 
    { 
     for(int i = 0; i < rc; ++i) 
     { 
      printf("%2d: %.*s\n", i, ovector[2*i+1] - ovector[2*i], str + ovector[2*i]); 
     } 
     offset = ovector[1]; 
    } 
    return 1; 
} 
+0

답변 해 주셔서 감사합니다. 그러나 나는 여전히 모든 경기를 출력하는 방법을 모른다. – tbmvp

+0

첫 번째 세트 만 나오 시나요? 정규식을 컴파일 할 때 PCRE_MULTILINE 옵션을 지정해야합니다. 자세한 내용은 http://www.pcre.org/pcre.txt를 참조하십시오. 예제를 업데이트하겠습니다. –

+0

필자는 필자가 생각하는대로 내 대답의 코드를 업데이트했습니다. 나는 PCRE 전문가가 아니라 랩퍼를 통해서만 사용했기 때문에 복잡하지는 않습니다. 나는 간부에게 1 번의 전화를 걸어 이것을 할 수있는 방법이있을 것이라고 생각한다. 문자열 인덱스가있는 ovector 배열을 모든 일치 항목으로 반환하도록합니다. 이 트릭을해야합니다. –

5

참고 : pcre_exec의 마지막 매개 변수()해야 요소 카운트, sizeof 연산자하지()! (http://www.pcre.org/readme.txt)

+1

또한 요소 수는 3의 배수 여야합니다 (예 : 100이 아님) – glob

+0

http://regexkit.sourceforge.net/Documentation/pcre/pcre_exec.html – glob