6

我有一个 .net 正则表达式,我正在使用 Windows Powershell 进行测试。输出如下:

> [System.Text.RegularExpressions.Regex]::Match("aaa aaa bbb", "aaa.*?bbb")


Groups   : {aaa aaa bbb}
Success  : True
Captures : {aaa aaa bbb}
Index    : 0
Length   : 11
Value    : aaa aaa bbb

我的期望是使用?量词会导致匹配为aaa bbb,因为第二组 a 足以满足表达式。我对非贪婪量词的理解是有缺陷的,还是我测试不正确?

注意:这与正则表达式 nongreedy is greedy显然不是同一个问题

4

4 回答 4

5

比较字符串的结果aaa aaa bbb bbb

regex: aaa.*?bbb 
result: aaa aaa bbb

regex: aaa.*bbb
result: aaa aaa bbb bbb

正则表达式引擎找到第一次出现的aaa,然后跳过所有字符(.*?)直到第一次出现bbb,但是对于贪婪运算符(.*),它将继续找到更大的结果,因此匹配最后一次出现的bbb

于 2013-05-19T09:57:41.827 回答
5

这是一个常见的误解。惰性量词不能保证最短的匹配。他们只确保当前位置的当前量词匹配的字符不超过整体匹配所需的字符。

如果您真的想确保尽可能短的匹配,则需要明确说明。在这种情况下,这意味着.*?您需要一个匹配任何既不是aaa也不是的子正则表达式,而不是bbb。因此,生成的正则表达式将是

aaa(?:(?!aaa|bbb).)*bbb
于 2013-05-19T14:19:08.757 回答
1

这不是一个贪婪/懒惰的问题。问题在于您的字符串是从左到右分析的。当第一个aaa匹配时,正则表达式引擎一个接一个地添加字符以获得完整的模式。

请注意,在您的示例中,通过贪婪行为,您将获得相同的结果:第一个aaa匹配,正则表达式引擎获取所有最后一个字符并逐个字符回溯,直到完全匹配。

于 2013-05-19T13:49:32.853 回答
0

嗯,这很简单,我们有以下字符串

啊啊啊bbb

让我们看看我们有这个正则表达式aaa.*?bbb。正则表达式引擎将以aaa

啊啊啊bbb

正则表达式引擎现在具有.*?bbb. 它将继续space

aaa空间aaa bbb

但我们仍然有一些字符,直到bbb?所以正则表达式引擎将继续它的方式并匹配第二组

aaa aaa 空间bbb

最后正则表达式引擎将匹配bbb

啊啊啊bbb


所以让我们看看,如果我们只想匹配第二个aaa,我们可以使用以下正则表达式:

(?<!^)aaa.*?bbb,这意味着匹配aaa不在句子开头的那个。

我们也可以使用aaa(?= bbb).*?bbb, 这意味着匹配aaa后面跟着的space bbb

看到它工作1 - 2

刚想起来,你为什么不直接使用aaa bbb呢?

于 2013-05-19T10:00:32.577 回答