Posted on 2010-04-12 13:14
小夜 阅读(5567)
评论(0) 编辑 收藏 引用 所属分类:
[61] Linux 、
[51] C&C++
工作中经常需要在正则表达式中使用方括号,比如匹配Linux系统命令行提示符“[root@localhost ~]# ”。在python中,可以使用正则表达式“[\[][^\[\]]*[\]][#|$] ”进行匹配,但在regex中此正则表达式无法正确匹配。
由于man手册中缺少对方括号转义的介绍,本文对regex中方括号的使用进行测试,测试程序如下:
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <regex.h>
int main(int argc, char** argv)
{
char * pattern, *mstr;
int x, z, lno = 0, cflags = REG_EXTENDED;
char ebuf[128], lbuf[256], format[32];
regex_t reg;
regmatch_t pm[10];
const size_t nmatch = 10;
pattern = argv[1];
z = regcomp(®, pattern, cflags);
if (z != 0)
{
regerror(z, ®, ebuf, sizeof(ebuf));
fprintf(stderr, "%s: pattern '%s' \n",ebuf, pattern);
regfree(®);
return 1;
}
while(fgets(lbuf, sizeof(lbuf), stdin))
{
++lno;
if ((z = strlen(lbuf)) > 0 && lbuf[z-1]== '\n') lbuf[z - 1] = 0;
z = regexec(®, lbuf, nmatch, pm, 0);
if (z == REG_NOMATCH)
{
printf("not match\n");
continue;
}
else if (z != 0)
{
regerror(z, ®, ebuf, sizeof(ebuf));
fprintf(stderr, "%s: regcom('%s')\n",
ebuf, lbuf);
return 2;
}
if (pm[0].rm_so!=-1)
printf("%04d: %s\n", lno, lbuf);
for (x = 0; x < nmatch && pm[x].rm_so != -1; ++ x)
{
mstr = strndup(lbuf + pm[x].rm_so, pm[x].rm_eo-pm[x].rm_so);
printf(" $%d: %s\n", x, mstr);
free(mstr);
}
fflush(stdout);
}
regfree(®);
return 0;
}
下面是对正则表达式“[\[][^\[\]]*[\]][#|$] ” 的测试,显然不符合要求。
./testreg "[\[][^\[\]]*[\]][#|$] "
[root@localhost bin]#
not match
[a\]#
0005: [a\]#
$0: [a\]#
从简单的开始先测试左括号“[”的匹配:
./testreg "[\[]+"
a
not match
[
0002: [
$0: [
[root@localhost bin]#
0003: [root@localhost bin]#
$0: [
再测试右括号“]”:
./testreg "[\]]+"
]
not match
\]
0002: \]
$0: \]
-----------------
./testreg "[]]+"
]]
0001: ]]
$0: ]]
两个简单的正则表达式可以看出:regex中左方括号需要转义,右方括号不需要转义。
下面我们再来测试匹配一下任意非方括号字符:
./testreg "[^\[]]+" //对[转义,不对]转义
[abc]
0001: [abc]
$0: c]
./testreg "[^\[\]]+" //对[和]转义
[abc]
0001: [abc]
$0: c]
./testreg "[^]\[]+" //对[转义,不对]转义,且把]放在^后使]不与前面的[匹配
[abc]
0001: [abc]
$0: abc
通过上面测试可以得出正确的正则表达式来匹配Linux命令行提示符——“[\[][^]\[]*[]][#$] ”或“\[[^]\[]*][#$] ”。