.net 非贪婪正则表达式量词给出贪婪结果
我有一个.net正则表达式,我正在使用Windows Powershell进行测试。结果如下:.net 非贪婪正则表达式量词给出贪婪结果,.net,regex,non-greedy,.net,Regex,Non Greedy,我有一个.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 我的期望
> [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足以满足表达式。我对非贪婪量词的理解是否有缺陷,或者我的测试是否有误
注意:这与比较字符串
aaa-aaa-bbb-bbb
的结果明显不同:
regex: aaa.*?bbb
result: aaa aaa bbb
regex: aaa.*bbb
result: aaa aaa bbb bbb
正则表达式引擎找到第一个出现的
aaa
,然后跳过所有字符(*?
),直到第一个出现的bbb
,但对于贪婪运算符(*
),它将继续查找更大的结果,从而匹配最后出现的bbb
) 其实很简单,我们有以下字符串
aaa bbb
让我们看看我们有这个正则表达式aaa.*?bbb
。正则表达式引擎将以aaa
aaaaaa bbb
正则表达式引擎现在具有*?bbb
。它将继续使用空格
aaa空格aaa bbb
但是我们仍然有一些字符,直到bbb
?因此,正则表达式引擎将继续它的方式,并匹配第二组
aaaaaa空间bbb
最后,正则表达式引擎将匹配bbb
:
regex: aaa.*?bbb
result: aaa aaa bbb
regex: aaa.*bbb
result: aaa aaa bbb bbb
aaa aaabbb
让我们看看,如果我们只想匹配第二个
aaa
,我们可以使用以下正则表达式:
(?),这意味着匹配不在句首的aaa
我们也可以使用aaa(?=bbb)。*?bbb
,这意味着匹配aaa
,后面紧跟空格bbb
看到它工作了吗
我刚刚意识到,但是为什么不直接使用aaa bbb
?这不是一个贪婪/懒惰的问题。问题在于从左到右分析字符串。当第一个aaa
匹配时,正则表达式引擎会逐个添加字符以获得完整的模式
请注意,对于贪婪行为,在您的示例中,您会得到相同的结果:第一个aaa
匹配,正则表达式引擎将获取所有最后的字符,并逐字符回溯,直到完全匹配为止。这是一个常见的误解。懒惰的量词不能保证最短的匹配。它们继续请确保当前位置的当前量词匹配的字符数不超过整体匹配所需的字符数
如果您确实希望确保尽可能短的匹配,则需要将其显式化。在这种情况下,这意味着您需要的子正则表达式不是*?
,而是与既不是aaa
也不是bbb
的任何对象匹配。因此,生成的正则表达式将是
aaa(?:(?!aaa|bbb).)*bbb
我只是做了我本来应该做的事,查阅了弗里德尔的相关章节。这让我想到了aaa((?!aaa)。)*bbb
,这或多或少是您所说的,只是您的答案中增加了使子表达式不捕获的详细信息,并且在否定前瞻中测试bbb。回答不错。这是对发生的事情的最清楚的解释。+1