在C中编译/匹配POSIX正则表达式
我正在尝试匹配字符串pcode
中的以下项目:
-
u
后面跟着一个或两位数字 -
phaseu
-
phasep
-
x
(由非单词字符包围) -
y
(由非单词字符包围) -
z
(由非单词字符包围)
我尝试使用POSIX正则表达式函数实现正则表达式匹配(如下所示),但有两个问题:
- 编译后的模式似乎没有子模式(即compiled.n_sub == 0)。
- 该模式在字符串“u0”中找不到匹配项,它确实应该!
我确信正则表达式字符串本身正在工作 – 它在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); }
看来你打算使用类似于“扩展”POSIX正则表达式语法的东西。 POSIX定义了两种不同的正则表达式语法,即“基本”(读取“过时”)语法和“扩展”语法。 要使用扩展语法,需要为regcomp
添加REG_EXTENDED
标志:
... 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:]]+)";