posts - 26, comments - 2, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

regex——正则表达式中使用方括号

Posted on 2010-04-12 13:14 小夜 阅读(5479) 评论(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(&reg, pattern, cflags);

        
if (z != 0)
        
{
                regerror(z, 
&reg, ebuf, sizeof(ebuf));
                fprintf(stderr, 
"%s: pattern '%s' \n",ebuf, pattern);
                regfree(
&reg);
                
return 1;
        }


        
while(fgets(lbuf, sizeof(lbuf), stdin))
        
{
                
++lno;
                
if ((z = strlen(lbuf)) > 0 && lbuf[z-1]== '\n') lbuf[z - 1= 0;

                z 
= regexec(&reg, lbuf, nmatch, pm, 0);
                
if (z == REG_NOMATCH)
                
{
                        printf(
"not match\n");
                        
continue;
                }

                
else if (z != 0)
                
{
                        regerror(z, 
&reg, 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(
&reg);
        
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命令行提示符——“[\[][^]\[]*[]][#$] ”或“\[[^]\[]*][#$] ”。

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理