2013-03-06 68 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