在C中编译/匹配POSIX正则表达式

时间:2009-06-23 11:47:52

标签: c regex posix

我正在尝试匹配字符串pcode中的以下项目:

  • u后跟1位或2位数字
  • phaseu
  • phasep
  • x(由非单词字符包围)
  • y(由非单词字符包围)
  • z(由非单词字符包围)

我尝试使用POSIX正则表达式函数实现正则表达式匹配(如下所示),但有两个问题:

  1. 编译后的模式似乎没有子模式(即compiled.n_sub == 0)。
  2. 该模式在字符串“u0”中找不到匹配,它确实应该!
  3. 我确信正则表达式字符串本身正在工作,因为它在python和TextMate中工作 - 我的问题在于C中的编译等。任何帮助实现这一点都将非常感激。

    提前感谢您的回答。

    if(idata=tb_find(deftb,pdata)){
        MESSAGE("Global variable!\n");
        char pattern[80] = "((u[0-9]{1,2})|(phaseu)|(phasep)|[\\W]+([xyz])[\\W]+)";
        MESSAGE("Pattern = \"%s\"\n",pattern);
        regex_t compiled;
        if(regcomp(&compiled, pattern, 0) == 0){
            MESSAGE("Compiled regular expression \"%s\".\n", pattern);
        }
    
        int nsub = compiled.re_nsub;
        MESSAGE("nsub = %d.\n",nsub);
        regmatch_t matchptr[nsub];
        int err;
        if(err = regexec (&compiled, pcode, nsub, matchptr, 0)){
            if(err == REG_NOMATCH){
                MESSAGE("Regular expression did not match.\n");
            }else if(err == REG_ESPACE){
                MESSAGE("Ran out of memory.\n");
            }
        }
        regfree(&compiled);
    }
    

1 个答案:

答案 0 :(得分:14)

似乎你打算使用类似于“扩展”POSIX正则表达式语法的东西。 POSIX定义了两种不同的正则表达式语法,一种是“基本”(读“过时”)语法和“扩展”语法。要使用扩展语法,您需要为REG_EXTENDED添加regcomp标志:

...
if(regcomp(&compiled, pattern, REG_EXTENDED) == 0){
...

如果没有此标志,regcomp将使用“基本”正则表达式语法。有一些重要的区别,例如:

  • 不支持|运营商
  • 子匹配的括号需要转义,\(\)

还应该注意, POSIX扩展正则表达式语法与Python的正则表达式不兼容<1> 1(不了解TextMate)。特别是,我担心你的regexp的这部分在POSIX中不起作用,或者至少不可移植:

 [\\W]

指定非空格字符的POSIX方式是:

 [^[:space:]]

你对POSIX的整个正则表达式应该在C:

中看起来像这样
 char *pattern = "((u[0-9]{1,2})|(phaseu)|(phasep)|[^[:space:]]+([xyz])[^[:space:]]+)";