懒惰的正则表达式不能按预期工作C#

时间:2010-06-21 07:52:03

标签: c# regex regex-greedy

我有以下正则表达式:a?\W*?b 我有一个字符串,.! ,b
在搜索匹配时,我得到了,.! ,b,但不仅仅是b。这是为什么?如何修改正则表达式以获得我需要的东西?
谢谢您的帮助。

7 个答案:

答案 0 :(得分:4)

懒惰的量词对你想要的东西没有帮助。让我们看看发生了什么。

正则表达式引擎从字符串的开头开始。首先尝试匹配a。它不能,但是没有问题,因为a是可选的。

然后,有一个懒惰的\W*?所以正则表达式引擎会跳过它但会记住当前的位置。

然后尝试匹配b。它不能,所以它回溯并成功地将,\W*?匹配。然后它继续尝试匹配b(因为懒惰的量词)。它仍然无法再次回溯。重复几次,直到最后正则表达式引擎到达b。现在比赛已经完成 - 正则表达式引擎宣布成功。

因此正则表达式按指定的方式工作 - 只是没有预期的那样。现在的问题是:你究竟想要正则表达式做什么?

例如,如果你真正想要的是:

单独匹配b,除非前面有a和一些非单词字符,在这种情况下匹配从ab的所有内容,然后使用

b|a\W*b

答案 1 :(得分:1)

懒惰的表达式只是从右侧延迟,即通过删除右侧的字符来尽可能短,但不会删除左侧的字符。

为了让匹配在稍后开始,你需要一个贪婪的表达式来吞下你不想匹配的字符。

或者,如Tim所示,如果第一个字符存在,您可以通过仅匹配第一个字符和以下分隔符来使匹配开始。

答案 2 :(得分:0)

例如,以下内容可能有效:(a\W*)?b

要更好地了解可能解决问题的方法,您应该包含更多示例。

答案 3 :(得分:0)

你的正则表达式匹配整个字符串,如下所示:

  1. a,零或一次重复(在这种情况下为“”)
  2. 任何不是字母数字的字符,任意数量的重复,尽可能少(“,。!”,在这种情况下)
  3. B'/ LI>

    在你的情况下,正则表达式匹配整个字符串,因此不会找到b(它没有找到同一部分的几个匹配项)。

    如果你搜索像',。!这样的字符串。 ,db'它会找到b。

答案 4 :(得分:0)

a?“我想要零个或a 的一个实例 - 这是满足的,因为零实例,然后是

\W*“我想要零个或多个非单词字符”,标点符号和空格字符满足,最后

b“匹配一个字母b,它确实如此。所以你的整个字符串都满足正则表达式。

如果您在任何人提出可能的解决方案之前提供更多可能的输入示例,这会有所帮助。

答案 5 :(得分:0)

您的示例未显示为什么a?是您的正则表达式的一部分,但为了仅匹配b字符串中的,.! ,b,您可以使用此类{{1} }}

这匹配(?=\W*?)b前面带有“非单词字符”的字符为零且未指定次数(尽可能少)

如果您只想在b等字符串中匹配说ab,则必须使用捕获组:a,.! ,b,其中第一组将保留(a?)\W*?(b)(如果有)和第2组a

答案 6 :(得分:0)

正则表达式称为贪婪或非贪婪是错误的。您可以在整个正则表达式中使用非贪婪量词,但它仍然会尽快启动匹配,如您所发现的那样。类似地,仅使用贪婪量词的正则表达式不能保证返回最长可能的匹配。例如,

Regex.Match("foo bar", @"\w+ (?:b|bar)")

...返回foo b,因为交替安排了第一个有效的替代方案,即使后一个方案会导致更长的匹配。 (请注意,我正在谈论像.NET这样的Perl派生的正则表达式;有些口味,比如awkegrep,确实能够支持最长的匹配。但是,因为那些口味不是' t有非贪婪量词,贪心不仅仅是默认模式,它只是 模式。)

简而言之,没有贪婪或非贪婪的正则表达式,只有贪婪或非贪婪的量词。