Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 非贪婪正则表达式量词给出贪婪结果_.net_Regex_Non Greedy - Fatal编程技术网

.net 非贪婪正则表达式量词给出贪婪结果

.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 我的期望

我有一个.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足以满足表达式。我对非贪婪量词的理解是否有缺陷,或者我的测试是否有误


注意:这与比较字符串
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