Regex.Matches每行返回一个匹配,而不是每个“word”

时间:2011-05-02 17:42:03

标签: c# .net regex

我很难理解为什么以下表达式\\[B.+\\]和代码返回匹配计数为1:

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

我想找到所有实例(让我们称之为“标签”)(在一个可变长度的HTML字符串标记,其中不包含换行符),前缀为 B 并用方括号括起来。

如果标记包含[BName],我会得到一个匹配 - 好。

如果标记包含[BName] [BAddress],我会得到一个匹配 - 为什么?

如果标记包含[BName][BAddress],我也只能获得一个匹配。

在一些基于网络的正则表达式测试人员中,我注意到如果文本包含CR字符,我将获得每行匹配 - 但我需要一些方法来指定我希望返回的匹配独立于换行符。

我也在MatchCollection的Groups and Captures系列中徘徊,但无济于事 - 总是只有一个结果。

3 个答案:

答案 0 :(得分:7)

你只得到一个匹配,因为默认情况下,.NET正则表达式是“贪婪的”;他们尝试尽可能地匹配一场比赛。

因此,如果您的值为[BName][BAddress],您将有一个匹配 - 这将匹配整个字符串;所以它会从开头的[B一直到 last ] - 而不是第一个。如果您想要两个匹配项,请改用此模式:\\[B.+?\\]

?之后的+告诉匹配引擎尽可能少地匹配......让第二组成为自己的匹配。

Slaks也指出了一个很好的选择;明确指出您希望将结尾]作为内容的一部分进行匹配,如下所示:\\[B[^\\]]+\\]这使得您的匹配“贪婪”,这可能会有用其他一些案例。在这个特定的例子中,可能没有太大区别 - 但是根据您可能正在处理的数据/模式,请记住这一点很重要。


另外,我建议使用C#“文字字符串”说明符@作为正则表达式模式,这样就不需要在正则表达式模式中双重转义;所以我会设置这样的模式:

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

这使得更容易找出更复杂的正则表达式

答案 1 :(得分:1)

请尝试使用正则表达式字符串\\[B.+?\\]。它自己.+(对于.*来说也是如此)会匹配尽可能多的字符,而.+?(或.*?)将与最低限度匹配字符数仍然满足表达的其余部分。

答案 2 :(得分:1)

.+是一场贪婪的比赛;它会尽可能地匹配。
在第二个示例中,它与BName] [BAddress匹配。

你应该写\[B[^\]]+\] [^\]]匹配除]之外的所有字符,因此它会被迫在第一个]之前停止。