Dou*_*oug 126 regex regex-greedy
我正在尝试使用正则表达式将字符串分成两部分.字符串格式如下:
text to extract<number>
Run Code Online (Sandbox Code Playgroud)
我一直在使用(.*?)<
,<(.*?)>
哪个工作正常,但在阅读了一点regex之后,我才开始想知道为什么我需要?
表达式中的.我通过这个网站找到它们之后才这样做,所以我不确定它们之间的区别.
pol*_*nts 162
默认情况下重复使用正则表达式是贪婪的:它们尝试匹配尽可能多的rep,当它不起作用并且它们必须回溯时,它们尝试一次匹配少一个rep,直到整个模式的匹配为止找到.结果,当匹配最终发生时,贪婪的重复将匹配尽可能多的代表.
该?
作为的重复数量更改此行为成为非贪婪,也被称为不愿(在例如,Java)(有时候"懒").相比之下,这种重复将首先尝试匹配尽可能少的代表,当这不起作用并且他们必须回溯时,他们开始匹配另一个rept一次.结果,当匹配最终发生时,不情愿的重复将匹配尽可能少的代表.
让我们比较这两种模式:A.*Z
和A.*?Z
.
鉴于以下输入:
eeeAiiZuuuuAoooZeeee
Run Code Online (Sandbox Code Playgroud)
模式产生以下匹配:
A.*Z
产生1个匹配:AiiZuuuuAoooZ
(见rubular.com)A.*?Z
产生2个匹配:AiiZ
和AoooZ
(参见rubular.com)让我们首先关注的是什么A.*Z
.当它匹配的第一个A
,在.*
,贪婪,首先尝试匹配尽可能多.
地.
eeeAiiZuuuuAoooZeeee
\_______________/
A.* matched, Z can't match
Run Code Online (Sandbox Code Playgroud)
由于Z
不匹配,引擎会回溯,然后.*
必须少一个.
:
eeeAiiZuuuuAoooZeeee
\______________/
A.* matched, Z still can't match
Run Code Online (Sandbox Code Playgroud)
这种情况发生了几次,直到最后我们才发现:
eeeAiiZuuuuAoooZeeee
\__________/
A.* matched, Z can now match
Run Code Online (Sandbox Code Playgroud)
现在Z
可以匹配,所以整体模式匹配:
eeeAiiZuuuuAoooZeeee
\___________/
A.*Z matched
Run Code Online (Sandbox Code Playgroud)
相比之下,A.*?Z
第一次匹配的不情愿重复尽可能少.
,然后.
根据需要采取更多.这解释了为什么它在输入中找到两个匹配项.
这是两种模式匹配的直观表示:
eeeAiiZuuuuAoooZeeee
\__/r \___/r r = reluctant
\____g____/ g = greedy
Run Code Online (Sandbox Code Playgroud)
在许多应用中,上述输入中的两个匹配是期望的,因此使用不情愿.*?
而不是贪婪.*
来防止过匹配.但是,对于这种特殊模式,使用否定字符类有一个更好的选择.
该模式A[^Z]*Z
还可以找到与A.*?Z
上述输入模式相同的两个匹配项(如ideone.com上所示).[^Z]
所谓的否定字符类:它匹配任何东西,但Z
.
两种模式之间的主要区别在于性能:更严格,否定的字符类只能匹配给定输入的一种方式.如果你对这个模式使用贪婪或不情愿的修饰符并不重要.事实上,在某些风格中,你可以做得更好,并使用所谓的占有量词,它根本不会回溯.
这个例子应该是说明性的:它显示了在给定相同输入的情况下,贪婪,不情愿和否定的字符类模式如何匹配.
eeAiiZooAuuZZeeeZZfff
Run Code Online (Sandbox Code Playgroud)
这些是上述输入的匹配:
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
Run Code Online (Sandbox Code Playgroud)
这些是stackoverflow上的问题和答案的链接,涵盖了一些可能感兴趣的主题.
Kob*_*obi 149
这是贪婪和非贪婪量词之间的区别.
考虑输入101000000000100
.
使用1.*1
,*
贪婪 - 它将一直匹配到最后,然后回溯直到它可以匹配1
,留下你1010000000001
.
.*?
不贪心.*
什么都不匹配,但之后会尝试匹配额外的字符,直到它匹配1
,最终匹配101
.
所有的量词有一个非贪婪模式:.*?
,.+?
,.{2,6}?
,甚至.??
.
在你的情况下,类似的模式可能是<([^>]*)>
-匹配任何东西,但一个大于号(严格来说,它的其他零个或多个字符匹配比>
在中间<
和>
).
Sim*_*mon 16
假设你有:
<a></a>
Run Code Online (Sandbox Code Playgroud)
<(.*)>
将匹配a></a
在那里为<(.*?)>
将匹配a
.后者在第一场比赛后停止>
.它检查一个或0个匹配,.*
然后是下一个表达式.
<(.*)>
匹配第一个表达式时,第一个表达式不会停止>
.它会一直持续到最后一场比赛>
.