。*之间的区别是什么? 和。*正则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式<(.*)>不会停止。 它会一直持续到最后一场比赛。