【问题标题】:Greedy Quantifiers贪心量词
【发布时间】:2013-06-16 14:05:38
【问题描述】:

我在阅读 K.Sierra 时发现了以下句子:

贪婪量词实际上确实读取了整个源数据,然后它就起作用了 向后(从右边)直到找到最右边的匹配。那时,它 包括从源数据的早期到并包括以下数据的所有内容 是最右边匹配的一部分。

现在,假设我们有如下来源:

"proj3.txt,proj1sched.pdf,proj1,proj2,proj1.java"

和模式:proj1([^,])*

为什么它不匹配整个文本?贪婪它应该匹配最右边的“proj1.java”并且返回的匹配应该是最右边匹配之前的整个源?相反,它返回:

proj1sched.pdf
proj1
proj1.java

【问题讨论】:

  • 对不起,我之前不清楚。我的意思是假设我将源代码指定为“xfooxxfoo”,将正则表达式指定为 .*foo,那么在这种情况下,为什么整个源代码(即 xfooxxfoo)都匹配?为什么和上面的例子不一样?

标签: java regex quantifiers


【解决方案1】:

我们有proj1([^,])*,其中 -

([^,])* 表示它将连接任意组合的子字符串 字符(出现零次或多次),不包含字符“,”和字符串“proj1”,如: “sched.pdf”或“”或“.java”这三个都不包含“,”字符。结果就是这样。

【讨论】:

    【解决方案2】:

    为什么不匹配整个文本?

    哦,试过了。但它在一个位置找到了序列p、r、o、j、1,然后继续找到零个或多个不是逗号的字符,因此匹配.、@987654327 @、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+ 没有任何可以匹配的东西,正则表达式失败。

    【讨论】:

      【解决方案3】:

      为什么它不匹配整个文本?

      因为你说它必须以proj1开头

      贪婪它应该匹配最右边的“proj1.java”

      正确。

      并且返回的匹配应该是最正确匹配之前的整个源?

      不知道你为什么会这样想,或者为什么会有用。如果这是你想要的,你可以做.*proj1.*。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-07-17
        • 2019-11-01
        • 2016-12-02
        • 1970-01-01
        • 1970-01-01
        • 2012-01-23
        • 2018-04-20
        • 1970-01-01
        相关资源
        最近更新 更多