2011-06-16 53 views
20

我已經繼承了一個包含以下正則表達式的代碼塊,並且我試圖瞭解它是如何得到它的結果的。C#中的正則表達式組

var pattern = @"\[(.*?)\]"; 
var matches = Regex.Matches(user, pattern); 
if (matches.Count > 0 && matches[0].Groups.Count > 1) 
    ... 

對於輸入user == "Josh Smith [jsmith]"

matches.Count == 1 
matches[0].Value == "[jsmith]" 

...我明白了。但後來:

matches[0].Groups.Count == 2 
matches[0].Groups[0].Value == "[jsmith]" 
matches[0].Groups[1].Value == "jsmith" <=== how? 

從我瞭解的羣體集合存儲在整場比賽以及之前的比賽看this question。但是,上面的正則表達式不僅僅匹配[方括號] [文本] [方括號],爲什麼「jsmith」匹配?

另外,它總是這樣的情況下,集合將存儲完全2組:整個比賽和最後一場比賽?

回答

17

()充當捕獲組所以比賽陣列具有所有的C#中找到匹配您的字符串和子陣列中的捕獲組的值都包含在這些匹配中。如果您不想要額外的捕獲級別,請刪除()

+0

如果你不想捕獲組使用'非捕獲groups'。 '(?:正則表達式)'。正則表達式參考:http://www.regular-expressions.info/refadv.html – BrunoLM 2011-06-16 17:19:31

+0

正確BrunoLM ::如果你需要邏輯組,但不希望它被捕獲。 – zellio 2011-06-16 17:20:20

2

圓括號也標識了一個組,所以匹配1是整個匹配,匹配2是方括號中找到的內容。

2

如何?答案就在這裏

(.*?) 

這是一個羣@「[(*?)];

1

組[0] - 是整個輸入字符串 組[1]是您的組通過括號(.*?)捕獲的,您可以配置正則表達式來僅捕獲顯式組(在創建正則表達式時有一個選項),或使用(?:.*?)創建非捕獲組。

54
  • match.Groups[0]總是和match.Value一樣,這是整個比賽。
  • match.Groups[1]是您的正則表達式中的第一個捕獲組。

考慮這個例子:

var pattern = @"\[(.*?)\](.*)"; 
var match = Regex.Match("ignored [john] John Johnson", pattern); 

在這種情況下,

  • match.Value"[john] John Johnson"
  • match.Groups[0]總是相同match.Value"[john] John Johnson"
  • match.Groups[1]是來自(.*?)的捕獲組。
  • match.Groups[2]是來自(.*)的捕獲組。
  • match.Groups[1].Captures是另一個維度。

考慮另一個例子:

var pattern = @"(\[.*?\])+"; 
var match = Regex.Match("[john][johnny]", pattern); 

需要注意的是,我們正在尋找在一排的一個或多個括號的名稱。您需要能夠分別獲取每個名稱。輸入Captures

  • match.Groups[0]總是一樣match.Value"[john][johnny]"
  • match.Groups[1]是來自(\[.*?\])+的捕獲組。在這種情況下與match.Value相同。
  • match.Groups[1].Captures[0]相同match.Groups[1].Value
  • match.Groups[1].Captures[1][john]
  • match.Groups[1].Captures[2][johnny]
+1

這個答案是幫助我把它放在一起(看起來像是來自投票,其他人也一樣),並且似乎更正確地解決了問題而不是接受的答案。 – 2014-03-29 19:21:01