2013-05-07 7 views
10

Teraz, gdy chcę przywrócić wszystkie pozycje meczu w str, takich jak:dlaczego regexec() w posix c zawsze zwraca pierwsze dopasowanie, jak może zwracać wszystkie pozycje meczów tylko raz?

abcd123abcd123abcd 

Przypuśćmy, że chcesz dostać wszystko „abcd”, muszę używać regexec(), uzyskać pierwszą pozycję: 0, 3, wtedy użyję:

123abcd123abcd 

jako nowy ciąg do ponownego użycia funkcji regexec() i tak dalej. Czytam instrukcję o regexec(), to mówi:

int regexec(const regex_t *preg, const char *string, size_t nmatch, 
       regmatch_t pmatch[], int eflags); 
nmatch and pmatch are used to provide information regarding the location of any 
matches. 

ale dlaczego nie to działa? To jest mój kod:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/types.h> 
#include <regex.h> 

int main(int argc, char **argv) 
{ 
    int i = 0; 
    int res; 
    int len; 
    char result[BUFSIZ]; 
    char err_buf[BUFSIZ]; 
    char* src = argv[1]; 

    const char* pattern = "\\<[^,;]+\\>"; 
    regex_t preg; 

    regmatch_t pmatch[10]; 

    if((res = regcomp(&preg, pattern, REG_EXTENDED)) != 0) 
    { 
     regerror(res, &preg, err_buf, BUFSIZ); 
     printf("regcomp: %s\n", err_buf); 
     exit(res); 
    } 

    res = regexec(&preg, src, 10, pmatch, REG_NOTBOL); 
    //~ res = regexec(&preg, src, 10, pmatch, 0); 
    //~ res = regexec(&preg, src, 10, pmatch, REG_NOTEOL); 
    if(res == REG_NOMATCH) 
    { 
     printf("NO match\n"); 
     exit(0); 
    } 
    for (i = 0; pmatch[i].rm_so != -1; i++) 
    { 
     len = pmatch[i].rm_eo - pmatch[i].rm_so; 
     memcpy(result, src + pmatch[i].rm_so, len); 
     result[len] = 0; 
     printf("num %d: '%s'\n", i, result); 
    } 
    regfree(&preg); 
    return 0; 
} 

./regex 'hello, world' 

wyjście:

num 0: 'hello' 

to moje wyjścia szacunku:

num 0: 'hello' 
num 1: 'world' 
+0

Pokaż nam, jak zadzwonić regexec. –

Odpowiedz

9

regexec wykonuje dopasowanie regex. Po znalezieniu dopasowania wyrażenie regularne zwróci wartość zero (tzn. Pomyślne dopasowanie). Parametr pmatch będzie zawierać informacje o tym jednym dopasowaniu. Pierwszy indeks tablicy (tj. Zero) będzie zawierał całe dopasowanie, kolejne indeksy tablicy zawierają informacje o grupach/podwyrażeniach przechwytywania.

wykazać:

const char* pattern = "(\\w+) (\\w+)"; 

dopasowane na "Hello World" będzie wyjście:

num 0: 'hello world' - entire match 
num 1: 'hello'  - capture group 1 
num 2: 'world'  - capture group 2 

(zobacz go w action)

W większości regex środowiskach zachowanie szukacie może mieć zostały uzyskane za pomocą modyfikatora globalnego:/g. Regexec nie udostępnia tego modyfikatora jako flagi ani nie obsługuje modyfikatorów. Będziesz więc musiał pętli, podczas gdy regexec zwraca zero począwszy od ostatniego znaku poprzedniego meczu, aby uzyskać wszystkie dopasowania.

Globalny modyfikator jest również niedostępny w bibliotece PCRE (słynna biblioteka regex C). Strony man PCRE mają do powiedzenia na ten temat:

Dzwoniąc pcre_exec() wiele razy z odpowiednimi argumentami, można naśladować/g opcja Perl

Powiązane problemy