为啥惰性量词后跟问号会变得贪婪? [复制]

Posted

技术标签:

【中文标题】为啥惰性量词后跟问号会变得贪婪? [复制]【英文标题】:Why do lazy quantifiers become greedy when followed by a question mark? [duplicate]为什么惰性量词后跟问号会变得贪婪? [复制] 【发布时间】:2019-12-02 11:32:42 【问题描述】:

为什么"hello".match(/^(.*?)?/)[0] 的计算结果为"h" 而不是""

换句话说,为什么在一个懒惰的表达式 (.*?) 后面加上一个零或一的量词 ? 会有点贪心?

【问题讨论】:

有趣的观察。但我不确定答案是否会非常令人兴奋。我的猜测是 ? 量词会产生很多零长度匹配,这非常没用 - 即使 /^.?/ 仅匹配 "h" 我不确定我是否会找到匹配 "" 的值,即使它是一个有效的结果。 @VLAZ:我完全找到了它的价值......事实上,它实际上导致了我的代码中的一个错误,因为它在我没想到的时候从字符串的其余部分中剥离了一个字符它到:( 更令人困惑 - "hello".match(/^(.*?)0,2/)[0] # => "he". @VLAZ:为什么要跳过它?取出第二个 ? 已经导致零长度匹配。把? 放回去根本不需要跳过那场比赛。我完全期待它匹配。 regex101 表明这仅适用于 javascript:regex101.com/r/3oYGgl/1。其他风味符合您的预期并返回零长度匹配。 【参考方案1】:

并不是内部量词变得贪婪,而是它试图避免匹配一个完全的部分。这就是为什么.* 仍然只匹配第一个字符,而不是整个单词。

这是 JavaScript 正则表达式的一个奇怪之处。带有贪婪量词的空匹配部分的处理方式与其他常见的正则表达式引擎略有不同。真正的原因是错综复杂的。见:Greediness behaving differently in JavaScript?

一种解决方法是使外部量词也变得惰性,并带有一个额外的问号:

"hello".match(/^(.*?)??/)[0] // output: ""

【讨论】:

哇,我明白了,谢谢!

以上是关于为啥惰性量词后跟问号会变得贪婪? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

re 模块

正则表达式加与星号的区别? [复制]

正则表达式加与星号的区别? [复制]

2018年4月28日笔记

为啥问号在 %% 内不起作用? [复制]

python全栈开发 * 30知识点汇总 * 180713