我有一个.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足以满足表达式。我对非贪婪量词的理解是否有缺陷,或者我测试不正确?
答案 0 :(得分:5)
比较字符串aaa aaa bbb bbb
的结果:
regex: aaa.*?bbb
result: aaa aaa bbb
regex: aaa.*bbb
result: aaa aaa bbb bbb
正则表达式引擎首次发现aaa
,然后跳过所有字符(.*?
)直到第一次出现bbb
,但对于贪婪的运算符( .*
)它会继续查找更大的结果,因此匹配bbb
的 last 次出现。
答案 1 :(得分:5)
这是一种常见的误解。懒惰量词不保证尽可能短的匹配。它们只确保当前位置的当前量词与总体匹配所需的字符数不匹配。
如果您真的想确保尽可能短的匹配,则需要明确说明。在这种情况下,这意味着您需要一个与.*?
和aaa
都不匹配的子规则,而不是bbb
。因此产生的正则表达式将是
aaa(?:(?!aaa|bbb).)*bbb
答案 2 :(得分:1)
这不是一个贪婪/懒惰的问题。问题在于从左到右分析您的字符串。当第一个aaa
匹配时,正则表达式引擎会逐个添加字符以获得完整的模式。
请注意,对于贪婪的行为,在您的示例中,您获得相同的结果:第一个aaa
匹配,正则表达式引擎获取所有最后的字符并逐个字符地回溯,直到完全匹配。< / p>
答案 3 :(得分:0)
嗯,这很简单,我们有以下字符串
aaa aaa bbb
让我们看看我们有这个正则表达式aaa.*?bbb
。正则表达式引擎将以aaa
aaa aaa bbb
正则表达式引擎现在.*?bbb
。它将继续space
aaa 空间 aaa bbb
但我们在bbb
之前仍有一些字符?所以正则表达式引擎将继续它的方式并匹配第二组
aaa aaa space bbb
最后,正则表达式引擎将匹配bbb
:
aaa aaa bbb
所以,让我们看看,如果我们只想匹配第二个aaa
,我们可以使用以下正则表达式:
(?<!^)aaa.*?bbb
,这意味着匹配不在句子开头的aaa
。
我们也可以使用aaa(?= bbb).*?bbb
,这意味着匹配aaa
之后的space bbb
。
刚刚感觉到,但为什么不直接使用aaa bbb
?