2013-05-07 95 views
10

现在,当我想回到str中所有匹配的岗位,如:为什么posix c中的regexec()总是返回第一个匹配,它如何返回所有匹配位置只运行一次?

abcd123abcd123abcd 

假设我想所有的“ABCD”,我必须用regexec(),得到的第一个位置:0,3,那么我将使用:

123abcd123abcd 

作为新字符串再次使用regexec(),等等。 我看了一下说明书regexec(),它说:

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. 

,但为什么不这项工作? 这是我的代码:

#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' 

输出:

num 0: 'hello' 

这是我关于输出:

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

向我们展示了如何调用regexec。 – 2013-05-07 11:10:48

回答

9

regexec执行一个正则表达式的匹配。一旦找到匹配,regexec将返回零(即成功匹配)。参数pmatch将包含有关该匹配的信息。第一个数组索引(即零)将包含整个匹配,后续数组索引包含有关捕获组/子表达式的信息。

为了证明:

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

的 “Hello World” 的匹配将输出:

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

(看到它在action

在大多数正则表达式的环境中,您寻求可能具有以下行为:通过使用全局修饰符获得:/ g。 Regexec不提供此修饰符作为标志,也不支持修饰符。 因此,您必须循环,而regexec从前一场比赛的最后一个字符开始返回零,以获得所有匹配

全局修饰符也无法使用PCRE库(着名的正则表达式C库)。该PCRE手册页有这样一段话吧:

通过调用pcre_exec()用适当的参数多次,你 可以模仿Perl的/ G选项

相关问题