2012-05-13 62 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的子字符串。