Posted on 2010-04-12 13:14
小夜 閱讀(5619)
評論(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命令行提示符——“[\[][^]\[]*[]][#$] ”或“\[[^]\[]*][#$] ”。