我正在阅读K.Sierra,发现了以下句子:
贪婪量词实际上确实读取了整个源数据,然后它就可以工作了 向后(从右侧(直到找到最右侧的匹配项。在这一点上,它 包括从源数据前面到以下数据的所有内容 是最右边匹配的一部分。
现在,假设我们有一个源,如下所示:
"proj3.txt,proj1sched.pdf,proj1,proj2,proj1.java"
和模式:proj1([^,])*
为什么它与全文不匹配?贪婪,它应该匹配最右边的"proj1.java",返回的匹配应该是最右边匹配之前的整个源?相反,它返回:
proj1sched.pdf
proj1
proj1.java
为什么它与全文不匹配?
因为你说它必须从proj1
开始
贪婪它应该与最右边的"proj1.java"相匹配
正确。
返回的匹配应该是最正确的匹配之前的整个源?
不知道你为什么会这么想,或者为什么这会有用。 你可以做.*proj1.*
如果这是你想要的。
为什么它与全文不匹配?
哦,它试过了。但是它在一个地方找到了序列p
、r
、o
、j
、1
,然后继续发现零个或多个字符不是逗号,因此匹配.
、p
、d
、f
。它停在那里,因为下一个字符是逗号,与[^,]
不匹配.
请注意,下一次匹配尝试将从下一个字符开始,即r
,依此类推,直到找到p
;当它找到一个时,它将尝试r
,等等。
正则表达式完全满意,引擎认为这是成功的,并且没有进一步尝试,即使在那点之外还有匹配。
因此,匹配的文本是proj1.pdf
。而不是整个输入。正则表达式是懒惰的,它们只匹配它们需要匹配的内容,并且永远不会更进一步。
但。这就是它变得有趣的地方。某些引擎无法以这种方式工作。
考虑正则表达式cat(|flap)
和输入文本catflap
。POSIX 已经尝试了正则表达式引擎,并规定正则表达式引擎应该匹配最左边、最长的匹配项。
因此,如果正则表达式引擎服从 POSIX,它应该匹配catflap
。但是现有的大多数正则表达式引擎在这里只会匹配cat
:空的交替首先匹配,正则表达式满意,故事结束!
现在,问题的核心:量词有三种类型,贪婪,懒惰和占有欲:
- 贪婪:默认,
*
; - 懒惰,又名过度使用:
*?
; - 占有欲:
*+
。
尽可能少的文本;所有格量词会尝试匹配尽可能多的文本,并且不会返回文本。
插图:这是输入文本:
The answer to everything is 42, says the mouse
下面是三个正则表达式,用于匹配此文本,并带有捕获组:
-
.*(d+)
(贪婪(; -
.*?(d+)
(懒惰(; -
.*+(d+)
(所有格(。
问题:小组将在这些表达式中捕获什么?答:
- 第一个:
2
; - 第二个:
42
; - 第三:甚至不会匹配文本!
.*+
会吞下一切,但不会回馈,d+
因此没有任何东西可以匹配,正则表达式失败。
我们有proj1([^,])*
其中 -
([^,])*
意味着它将连接任意组合的子字符串字符(出现零次或多次(,不包含字符 '","和字符串"proj1",如下所示:"sched.pdf"或"或".java"这三个字符都不包含","字符。因此结果。