。*之间的区别是什么? 和。*正则expression式?

我想使用正则expression式将一个string分成两部分。 该string格式如下:

text to extract<number> 

我一直使用(.*?)<<(.*?)>工作正常,但读了一些正则expression式,我刚开始想知道为什么我需要? 在expression式中。 我只是通过这个网站find他们之后才这样做的,所以我不确定它们有什么不同。

    这是贪婪和非贪婪量词的区别。

    考虑input101000000000100

    使用1.*1*是贪婪的 – 它将一直匹配到最后,然后回溯到匹配1 ,留下1010000000001
    .*? 是非贪婪的。 *将不匹配,但会尝试匹配多余的字符,直到匹配1 ,最终匹配101

    所有的量词都有一个非贪婪的模式: , .+?.{2,6}? ,甚至.??

    在你的情况下,一个类似的模式可以是<([^>]*)>匹配任何东西,但大于号(严格来说,它匹配零或多个字符,而不是>之间的<> )。

    参见量词小抄

    贪婪与非贪婪

    在regex默认情况下重复贪婪 :他们尽可能匹配尽可能多的代表,当这不工作,他们不得不回溯,他们试图匹配一次less一个代表,直到整个模式的匹配是find。 结果,当一场比赛最终发生时,贪婪的重复将尽可能地匹配尽可能多的代表。

    这个? 作为一个重复量词将这种行为改变为非贪婪 ,也被称为不情愿 ( 例如Java )(有时是“懒惰”)。 相反,这种重复将首先尝试尽可能less地进行匹配,当这种做法不起作用并且不得不倒退时,他们会再次匹配一次。 因此,当一场比赛最终发生时,不愿意重复的比赛将会尽可能less地进行。

    参考

    • regular-expressions.info/Repetition – 懒惰而不是贪婪

    例1:从A到Z

    我们来比较这两种模式: A.*ZA.*?Z

    鉴于以下input:

     eeeAiiZuuuuAoooZeeee 

    模式产生以下匹配:

    • A.*Z产生1个匹配: AiiZuuuuAoooZ ( 参见rubular.com )
    • A.*?Z产生2个匹配: AiiZAoooZ ( 参见rubular.com )

    我们先来关注A.*Z所做的。 当它与第一个A相匹配时, .* ,贪婪,首先尝试匹配尽可能多的. 尽可能。

     eeeAiiZuuuuAoooZeeee \_______________/ A.* matched, Z can't match 

    由于Z不匹配,所以发动机回路和.*必须匹配一个.

     eeeAiiZuuuuAoooZeeee \______________/ A.* matched, Z still can't match 

    这发生了几次,直到最后我们来到这个:

     eeeAiiZuuuuAoooZeeee \__________/ A.* matched, Z can now match 

    现在Z可以匹配,所以整体模式匹配:

     eeeAiiZuuuuAoooZeeee \___________/ A.*Z matched 

    相比之下, A.*?Z的不情愿重复首先相匹配. 尽可能,然后采取更多. 有必要的。 这解释了为什么它在input中find两个匹配。

    以下是两种模式匹配的可视化表示:

     eeeAiiZuuuuAoooZeeee \__/r \___/rr = reluctant \____g____/ g = greedy 

    示例:另一种方法

    在许多应用中,上述input中的两个匹配是所期望的,因此是不愿意的.*? 被用来代替贪婪.*来防止过度匹配。 然而,对于这个特定的模式,有一个更好的select,使用否定字符类。

    模式A[^Z]*Z也可以find与上面input的A.*?Z模式相同的两个匹配( 如在ideone.com上所见 )。 [^Z]就是所谓的否定字符类 :除了Z任何字符

    两种模式的主要区别在于性能:更严格的是,否定的字符类只能匹配给定input的一种方式。 这个模式使用贪婪或不情愿的修饰符并不重要。 事实上,在某些方面,你可以做得更好,使用所谓的占有量词,它根本不会回溯。

    参考

    • regular-expressions.info/Repetition – 一个替代懒惰 , 否定的字符类和所有量词

    例2:从A到ZZ

    这个例子应该是说明性的:它显示了贪婪的,不愿意的和否定的字符类模式在给定相同的input的情况下如何匹配。

     eeAiiZooAuuZZeeeZZfff 

    这些是上述input的匹配:

    • A[^Z]*ZZ产生1个匹配: AuuZZ ( 如在ideone.com上所见 )
    • A.*?ZZ产生1个匹配: AiiZooAuuZZ ( 在ideone.com上看到 )
    • A.*ZZ产生1个匹配: AiiZooAuuZZeeeZZ ( 在ideone.com上看到 )

    以下是他们匹配的视觉表示:

      ___n / \ n = negated character class eeAiiZooAuuZZeeeZZfff r = reluctant \_________/r / g = greedy \____________/g 

    相关话题

    这些链接的问题和答案在计算器覆盖了一些可能感兴趣的话题。

    一个贪婪的重复可以超过另一个

    • 正则expression式不够贪婪
    • 正则expression式:谁是贪婪的

    假设你有:

     <a></a> 

    <(.*)>会匹配a></a ,其中<(.*?)>会匹配a 。 后者在第一场比赛后停止。 它检查.*之后的一个或0个匹配,然后是下一个expression式。

    匹配第一个>时,第一个expression式<(.*)>不会停止。 它会一直持续到最后一场比赛。