2013-03-06 72 views
3

我使用C中的PCRE正则表达式库(http://www.pcre.org/)来解析和匹配我的HTML字符串。为了简化我的问题,假设我得到了源字符串:“AAA:BBBB:”,我的模式:一个(*):| B:,符号(*?)?表明它是一个非贪婪匹配,所以答案应该是两个对决:一个是“AAA:”和其他“BBBB:”使用PCRE的奇怪答案正则表达式

然后我编程:

char *src = "aaa: bbbb:"; 
char *pattern = "a(.*?):|b(.*?):"; 
pcre *re = NULL; 

//---missing out--- 

re = pcre_compile(pattern, // pattern, 
        0,   // options, 
        &error,  // errptr, 
        &erroffset, // erroffset, 
        NULL);  // tableptr, 
while (
     (rc = pcre_exec(re,  // regex ptr, 
       NULL,   // extra arg, 
       src,   // subject, 
       strlen(src), // length, 
       0,    // startoffset, 
       0,    // options, 
       ovector,  // ovector, 
       OVECCOUNT)  // ovecsize, 
    )!=PCRE_ERROR_NOMATCH) 
    { 
     printf("\nOK, string has matched ...there are %d matchups\n\n",rc); // 
     for (i = 0; i < rc; i++) 
     { 
      char *substring_start = src + ovector[2*i]; 
      int substring_length = ovector[2*i+1] - ovector[2*i]; 
      printf("$%2d: %.*s length: %d\n", i, substring_length, substring_start,substring_length); 
     } 
     src = src + ovector[1]; // to move the src pointer to the end offset of current matchup 
     if (!src) break; 
    } 
pcre_free(re); 

我得到了我的结果:

Source : aaa: bbbb: 
Pattern: "a(.*?):|b(.*?):" 

OK, string has matched ...there are 2 matches 

$ 0: aaa: length: 4 
$ 1: aa length: 2 

OK, string has matched ...there are 3 matches 

$ 0: bbbb: length: 5 
$ 1: length: 0 
$ 2: bbb length: 3 

我不知道,我怎么会得到答案“$ 1:长度:0”

// -------------------------------------------- --------------------------------------------

@Jonathan勒夫勒我认为你的回答是正确的。

刚才我试着

Source: "aaa: bbb: ccc:" 
Pattern: "c(.+?):|a(.+?):|b(.+?):" 

,并得到了结果是这样的:

$ 0: aaa: length: 4 
$ 1: length: 0 
$ 2: aa length: 2 

$ 0: bbbb: length: 5 
$ 1: length: 0 
$ 2: length: 0 
$ 3: bbb length: 3 

$ 0: cccc: length: 5 
$ 1: ccc length: 3 

这证明你的答案相反:

正则表达式的捕获时停止对决被发现,所以aaa:a(.+?):被捕获后尝试匹配c(.+?):,并且结果的第一行显示整个字符串时,#2示出结果失调匹配了替代c(.+?):

对于b(。+?),它被认为是最后的正则表达式所捕获,即说明了这两种length : 0

对于C(。+? ),它首先被捕获,所以没有length : 0

+0

你能否扩充示例源代码以便编译? – thuovila 2013-03-06 11:46:38

+0

也许是因为你使用'*'而不是'+' – jcubic 2013-03-06 11:48:42

回答

1

在正则表达式中有两个捕获,每个替代都有一个捕获。但是,捕获从左到右编号。在第二种情况下,第一个($1)捕获为空;没有a的匹配,所以第一次捕获是空的;第二个($2)捕获有你期望的b

更令人惊讶的是,第一次匹配时没有为第二次捕获指定任何内容。如果没有他们的数据,我想这些捕获是空的。

+0

谢谢!我认为你的回答是正确的〜 – 2013-03-06 15:07:17

0

A *表示任何数字,包括零的字符。这意味着它匹配“无”。应该使用+字符代替,表示“匹配至少1”。

+0

它并不回答为什么它存在的问题。 – nhahtdh 2013-03-06 13:59:48

+0

我试过一个(。+?),结果也一样 – 2013-03-06 15:11:28

0

尝试使用模式char *pattern = "a+?:|b+?:";

编辑注意到,刚刚"a+:|b+:"也会起作用。

+1

问题是为什么会发生,而不是针对正则表达式的建议,这可能是一个显示奇怪的例子。 – nhahtdh 2013-03-06 14:01:02

0

图案:

a(.*?): 

这种模式意味着寻找一个未捕获“A”,其次是什么的任何量的捕获,被修改为返回最小的匹配模式,接着是未捕获的“:” 。

如果考虑字符串:

aaa: 

现在想想最后一个 '一' 冒号前:

a: 

它的模式匹配 - 一个 'A',后面什么都没有,接着是冒号。 '没有'被捕获,这就是为什么你得到一个零长度的结果。

+0

第二场比赛所捕获的整个字符串是'bbbb';涉及“a:”的解释显然不适用。 – 2013-03-06 14:51:02

+0

对不起,我没有给出一个关于我的真实问题的好例子,但是你的回答不能解释为什么在'aaa:'结果中有'length:0' – 2013-03-06 15:19:17