2011-05-02 73 views
4

我有一個很難理解爲什麼下面的表達式\\[B.+\\]和代碼返回匹配數的1:Regex.Matches返回每行一個比賽,不是每個「單詞」

string r = "\\[B.+\\]"; 
return Regex.Matches(Markup, sRegEx); 

我想找到所有的實例(讓我們稱之爲'標籤')(在不包含換行符的可變長度HTML字符串標記中),其前綴爲B並且括在方括號中。

如果標記包含[BName],我會得到一個匹配 - 好。

如果標記包含[BName] [BAddress],我得到一個匹配 - 爲什麼?

如果標記包含[BName][BAddress],我也只得到一個匹配。

在一些基於Web的正則表達式測試人員中,我注意到如果文本包含一個CR字符,每行都會得到一個匹配 - 但我需要某種方式來指定我想要的匹配返回獨立於換行符。

我也在MatchCollection的Groups和Captures集合中探索過,但無濟於事 - 總是隻有一個結果。

回答

7

由於缺省情況下,.NET正則表達式爲「貪婪」,因此您只能獲得一個匹配項;他們儘可能地匹配一場比賽。

所以如果你的值是[BName][BAddress]你將有一個匹配 - 它將匹配整個字符串;所以它會匹配從[B開始一直到最後] - 而不是第一個。如果你想兩場比賽,用這個模式來代替:\\[B.+?\\]

+?告訴匹配引擎匹配儘可能少的......離開第二組是其自己的比賽。

鐵匠還指出了一個很好的選擇;特別指定你不要希望匹配結尾]作爲內容的一部分,如下所示:\\[B[^\\]]+\\]這會使匹配保持「貪婪」,這在某些情況下可能會有用。在這個特定的例子中,可能沒有太大的區別 - 但根據您可能特別處理的數據/模式,記住一件重要的事情。


在一個側面說明,我建議使用C#「文本字符串」符@對正則表達式模式,讓您無需爲雙逃逸的東西正則表達式模式;因此,我將設置模式,象這樣:

string pattern = @"\[B.+?\]"; 

這使得它更容易弄清楚正則表達式是更復雜的

+1

真棒 - 提示,寫得很好,甚至包括一些額外的提示!非常感謝。 – 2011-05-02 18:22:20

1

嘗試正則表達式字符串\\[B.+?\\]代替。.+(對於.*也是如此)將匹配儘可能多的字符,而.+?(或.*?)將匹配字符的最小數目,同時仍然滿足表達式的其餘部分。

+0

+1還提到'?'量詞修飾符在用作量詞時也可以用於'*'。信不信由你,它也可以用來反對'?'。請注意,使用'*'和'?',如果可能的話,它會嘗試匹配0次。有時候會導致看起來很奇怪的結果。 – 2011-05-02 19:06:55

1

.+是一個貪婪的匹配;它會盡可能匹配。
在你的第二個例子中,它匹配BName] [BAddress

你應該寫\[B[^\]]+\]
[^\]]與除]之外的每個字符匹配,所以它被迫在第一個]之前停止。

+0

+1;這可能是比我最初發布的單個更好的選擇,具體取決於所討論的數據。它在* this *方面可能沒有什麼區別,但在匹配看起來像'tag'的東西的一般情況下可能會更好。我添加了這個(與歸屬)到我的答案。 – 2011-05-02 17:53:54

相關問題