。*之间的区别是什么? 和。*正则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.*Z
和A.*?Z
。
鉴于以下input:
eeeAiiZuuuuAoooZeeee
模式产生以下匹配:
-
A.*Z
产生1个匹配:AiiZuuuuAoooZ
( 参见rubular.com ) -
A.*?Z
产生2个匹配:AiiZ
和AoooZ
( 参见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式<(.*)>
不会停止。 它会一直持续到最后一场比赛。