2012-05-13 100 views
1

的模式的多個匹配項時的行爲與預期不符預期我的目標是在文本中查找某些模式的所有匹配項。 比方說,我的模式是:.NET Regex.Matches在查找包含*()

h.*o 

這意味着我在尋找任何文本開始'h''o'結束並具有(也爲零)之間的任意數字字符的。

我的理解是,方法Matches()將提供多個匹配根據描述(見MSDN)。

const string input = "hello hllo helo"; 
Regex regex = new Regex("h.*o"); 

var result = regex.Matches(input); 
foreach (Match match in result) 
{ 
    Console.WriteLine(match.Value); 
} 

我的期望是:

1. "hello" 
2. "hllo" 
3. "helo" 
4. "hello hllo" 
5. "hello hllo helo" 

令我驚訝返回比賽只包含一個字符串 - 整個輸入字符串。

"hello hllo helo" 

問題:

  1. 哪一個是錯誤的:我的意料,我的正則表達式或階級的使用情況如何?
  2. 如何實現我的例子中顯示的結果?

在此先感謝。

回答

3

*貪婪 - 它會嘗試匹配儘可能多的字符。您可以通過問號下面這使它不願,但更好的方法是從列表中排除o如果字符.比賽,像這樣:

h[^o]*o 

這裏是一個link來很好的解釋貪婪與不願意。

2

除了這個事實,*是貪心,所述Matches方法僅發現非重疊匹配;也就是說,它查找從最後一場比賽中止的位置開始的每個後續比賽。從MSDN Library

通常,正則表達式引擎開始搜索下一個匹配,確切地說,在上一次匹配停止的位置。

因此,即使你使用*?h[^o]*o,而不是*,也仍然只能找到「你好」,「hllo」和「直升機」。

我不知道是否有Regex內置的方法來有效地找到所有匹配指定模式的可能子,但你可以通過所有可能的子環自己,檢查每一個匹配:

const string input = "hello hllo helo"; 
Regex regex = new Regex("^h.*o$"); 

for (int startIndex = 0; startIndex < input.Length - 1; startIndex++) 
{ 
    for (int endIndex = startIndex + 1; endIndex <= input.Length; endIndex++) 
    { 
     string substring = input.Substring(startIndex, endIndex - startIndex); 
     if (regex.IsMatch(substring)) 
      Console.WriteLine(substring); 
    } 
} 

輸出:

hello 
hello hllo 
hello hllo helo 
hllo 
hllo helo 
helo 

請注意,我說^$的正則表達式,以確保它的整個匹配substring,而不僅僅是substring的子字符串。