2013-10-15 68 views
0

在匹配正則表達式時,我想從結果中排除noncapturing groups。我錯誤地認爲他們會被默認排除,因爲他們被稱爲非捕獲組。爲什麼Regex.Match在結果中包含非捕獲組?

由於某些原因,Regex.Match表現得好像我還沒有指定一個非捕獲組。嘗試在立即窗口中運行以下命令:

System.Text.RegularExpressions.Regex.Match("b3a",@"(?:\d)\w").Value 

我希望得到的結果是

"a" 

但它實際上是

"3a" 

This question建議我看組,但只有結果中的一個組也是「3a」。它包含一個捕獲,也是「3a」。

這是怎麼回事? Regex是否被竊聽,還是有我需要設置的選項?

回答

8

匹配與捕獲不同。 (?:\d)僅僅意味着匹配一個包含\d的子模式,但不要打擾將其放入捕獲組。您的整個模式(?:\d)\w尋找(?:\d),然後是\w;它的功能等同於\d\w

如果你想匹配,只有當它是由\d前面有一個\w,使用向後斷言,而不是:

System.Text.RegularExpressions.Regex.Match("b3a", @"(?<=\d)\w").Value 
+3

或'@ 「\ d(\ w)的」 匹配'並根據需要使用這些組。我發現更容易閱讀(雖然它可能會更慢,不知道) –

3

非捕獲組意味着它不組成組。匹配字符串包含在結果字符串中。

如果要排除該部分,請使用lookbehind斷言等內容。

@"(?<=\d)\w" 
3

你誤解的非捕獲組的目的。

一般來說,基團(由一對括號()的定義)意味着兩兩件事:

  • 所包含的正則表達式進行分組,因此,括號之後的任何量詞應用於整個表達,而不僅僅是前單個字符。
  • 與該組匹配的子字符串被存儲爲Groups屬性中的子捕獲。

有時候,你不想對某些羣體的第二個結果,這就是爲什麼非捕獲組進行了介紹:他們讓你組一個子表達式,而不必在Groups財產存放在項目的任何比賽。

你已經注意到,您的Groups屬性包含一個項目,雖然 - 這是真的,因爲默認情況下,第一組始終是完整表達的捕獲。比照在文檔中:

如果正則表達式引擎可以找到匹配項,則由Groups屬性返回的GroupCollection對象的第一個元素包含一個匹配整個正則表達式模式的字符串。


你仍然可以使用組來達到你想要什麼,通過將要捕捉成一組字符串:

\d(\w) 

(我再次離開了非捕獲組因爲它不會改變上述表達式中的任何內容。)

通過此修改的表達式,匹配項中的Groups屬性應該包含2個項目:

  1. (的\d\w
  2. 只有上面的字符串的一部分,完整的比賽,你似乎是有意,通過\w
相關問題