我试图用正则表达式将字符串分成两部分。字符串的格式如下:
text to extract<number>
我一直在使用(.*?)<和<(.*?)>,这工作很好,但在阅读正则表达式一点之后,我才开始怀疑为什么我需要?在表达式中。我只是在通过这个网站找到他们之后才这样做的,所以我不太确定有什么区别。
我试图用正则表达式将字符串分成两部分。字符串的格式如下:
text to extract<number>
我一直在使用(.*?)<和<(.*?)>,这工作很好,但在阅读正则表达式一点之后,我才开始怀疑为什么我需要?在表达式中。我只是在通过这个网站找到他们之后才这样做的,所以我不太确定有什么区别。
当前回答
假设你有:
<a></a>
<(. *) >将匹配一个> < / <(. * ?)>将匹配。 后者在>的第一场比赛结束后停止。它检查的是1 或者0次匹配。*后跟下一个表达式。
第一个表达式<(.*)>在匹配第一个>时不停止。将持续到>的最后一场比赛。
其他回答
贪婪vs非贪婪
regex中的重复在默认情况下是贪婪的:它们尝试匹配尽可能多的代表,当这不起作用时,它们必须返回,它们尝试一次匹配更少的代表,直到找到整个模式的匹配。因此,当匹配最终发生时,贪婪重复会匹配尽可能多的重复。
的吗?作为重复量词,将这种行为变为非贪婪,也称为不情愿(在Java中)(有时也称为懒惰)。相比之下,这种重复会首先尝试尽可能少的重复,当这种方法不起作用时,他们不得不后退,他们会开始一次重复一次。因此,当匹配最终发生时,不情愿的重复会匹配尽可能少的重复次数。
参考文献
regular-expressions.info/Repetition -用懒惰代替贪婪
例1:从A到Z
让我们比较这两种模式:A.*Z和A.*?Z。
给定以下输入:
eeeAiiZuuuuAoooZeeee
这些模式产生以下匹配项:
A.*Z产生1个匹配:AiiZuuuuAoooZ(见rubular.com) a . * ?Z产生2个匹配:AiiZ和AoooZ(见rubular.com)
让我们首先关注a *Z做了什么。当它匹配第一个A时,贪婪的。*首先尝试匹配尽可能多的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第一个匹配的数量一样少。尽可能的多,然后再多吃药。这是很有必要的。这解释了为什么它在输入中找到两个匹配项。
下面是两种模式匹配的视觉表现:
eeeAiiZuuuuAoooZeeee
\__/r \___/r r = reluctant
\____g____/ g = greedy
示例:替代方案
在许多应用中,上述输入中的两个匹配是所需要的,因此不情愿。*?用来代替贪婪的。*,以防止过度匹配。然而,对于这个特定的模式,有一个更好的选择,使用反字符类。
模式A[^Z]*Z也找到了与A *?以上输入的Z模式(如ideone.com所示)。[^Z]是所谓的否定字符类:它匹配除Z以外的任何字符。
这两种模式之间的主要区别在于性能:更严格地说,对于给定的输入,负字符类只能匹配一种方式。对于这种模式,使用贪婪修饰符还是不情愿修饰符都没有关系。事实上,在某些情况下,你甚至可以做得更好,使用所谓的所有格量词,这根本不会回溯。
参考文献
regular-expressions.info/Repetition -替代懒惰,否定字符类和所有格量词
例2:从A到ZZ
这个例子应该是说明性的:它展示了给定相同的输入,贪婪、不情愿和否定字符类模式如何不同地匹配。
eeAiiZooAuuZZeeeZZfff
这些是上面输入的匹配项:
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
相关的话题
这些链接指向stackoverflow上的问题和答案,涵盖了一些可能感兴趣的主题。
一次贪婪的重复可以胜过另一次贪婪
正则表达式不够贪婪 正则表达式:谁更贪婪
它是贪婪量词和非贪婪量词之间的区别。
考虑输入101000000000100。
使用1。*1, *是贪婪的-它将一直匹配到最后,然后回溯到它可以匹配1,留下1010000000001。 . * ?是贪婪的。*将不匹配任何字符,但将尝试匹配额外的字符,直到匹配1,最终匹配101。
所有量词都有一个非贪婪模式:.*?, + ?, {2,6} ?,甚至……??
在您的例子中,类似的模式可以是<([^>]*)> -匹配除大于号以外的任何字符(严格地说,它在<和>之间匹配除>之外的零或多个字符)。
参见量词小抄。
假设你有:
<a></a>
<(. *) >将匹配一个> < / <(. * ?)>将匹配。 后者在>的第一场比赛结束后停止。它检查的是1 或者0次匹配。*后跟下一个表达式。
第一个表达式<(.*)>在匹配第一个>时不停止。将持续到>的最后一场比赛。