我理解 ?
标记在这里表示“懒惰”。
我的问题本质上是 [0-9]{2}?
与 [0-9]{2}
它们一样吗?
如果是这样,我们为什么要写前一个表达式?惰性模式不是更昂贵的性能吗?
如果不是,你能说出区别吗?
最佳答案
什么是“惰性”(勉强)匹配?
与正则表达式匹配时,指针默认贪心:
Left | Right
\d+ 12345
^ ^
\d+ 12345
^ ^^^^^ Matched!
懒惰是贪婪的对立面:
Left | Right
\d+? 12345
^ ^
\d+? 12345
^^ ^
12345
^
12345
^
12345
^ Matched!
为什么重要?
在比赛中,量词 *
+
?
默认情况下是贪婪的。这可能会导致不需要的行为,尤其是当我们希望某些字符仅在需要完成匹配时才匹配,否则忽略。
一个典型的例子是当我们想要匹配单个 XML 标签时:我们将通过 <.*>
来失败。 .
Left | Right
<.*> <p>hi</p><br /><p>bye</p>
^ ^
<.*> <p>hi</p><br /><p>bye</p>
^^ ^^^^^^^^^^^^^^^^^^^^^^^^
<.*> <p>hi</p><br /><p>bye</p>
^ < [backtrack!]
<.*> <p>hi</p><br /><p>bye</p>
^ ^ Matched "<p>hi</p><br /><p>bye</p>"!
Left* | Right
<.*?> <p>hi</p><br /><p>bye</p>
^ ^
<.*?> <p>hi</p><br /><p>bye</p>
^^^ ^ [can we stop? we're lazy [yes]]
<.*?> <p>hi</p><br /><p>bye</p>
^ ^ Matched "<p>"!
什么可以量化为懒惰?
您可以添加 ?
在量词和范围后面构造:
+
(一个或多个),*
(零个或多个),?
(可选);
{n,m}
(在 n 和 m 之间,其中 n < m),{n,}
(n 或更多),{n}
(恰好 n 次)。
(例子中的n和m为实数且满足n, m ε N)
不情愿的量词不愿继续前进。
考虑到引擎仅在绝对必要时尝试匹配以使其余部分成功,允许匹配尽可能多或尽可能少。见以下案例:Left | Right abc* abccccd ^ ^ abc* abccccd ^ ^ abc* abccccd ^ ^ abc* abccccd ^^ ^^^^ Matched "abcccc"!
Left* | Right abc*? abccccd ^ ^ abc*? abccccd ^ ^ abc*? abccccd ^^^ ^ [must we do this? we're lazy [no]] Matched "ab"!
正如所展示的,它们匹配得越少越好。
不情愿的量词放弃取悦其他量词。
(演示目的;如果有人问,我没有告诉您可以这样使用 RegExp。)Left | Right c+c+ abccccd ^ ^ c+c+ abccccd ^^ ^^^^ c+c+ abccccd ^ < [backtrack] c+c+ abccccd ^^ ^ Matched "cccc"! (c+ -> @ccc; c+ -> @c)
Left* | Right c+?c+ abccccd ^ ^ c+?c+ abccccd ^^^ ^ [pass] c+?c+ abccccd ^^ ^^^ Matched "cccc"! (c+? -> @c; c+ -> @c)
- 精确范围量词不受影响。
X{n}
之间和X{n}?
,几乎没有区别;大多数引擎在内部优化掉了不情愿的标志。这是因为惰性构造仅在匹配是动态的情况下适用,其中引擎可以针对量词(需要或贪婪)以一种或另一种方式表现,但不适用于这种情况。
查看 regex101 ,一个完善的正则表达式引擎,附带解释和调试器日志,向您展示指针步骤。 另请阅读 The Stack Overflow Regex Reference !
关于regex - 关于问号 "lazy"模式的正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25728576/