*的区别是什么?和。*正则表达式?

我试图用正则表达式将字符串分成两部分。字符串的格式如下:

text to extract<number>

我一直在使用(.*?)<<(.*?)>,它们工作得很好,但在阅读了regex一点后,我开始怀疑为什么我需要在表达式中使用?。我只是在通过这个网站找到他们之后才这样做的,所以我不太确定有什么区别。

152523 次浏览

假设你有:

<a></a>

<(.*)>将匹配a></a,其中<(.*?)>将匹配a。 后者在>的第一次匹配之后停止。它检查的是1 或.*的0个匹配,后跟下一个表达式

第一个表达式<(.*)>在匹配第一个>时不会停止。它将一直持续到>的最后一个匹配。

它是贪婪量词和非贪婪量词之间的区别。

考虑输入101000000000100

使用1.*1*是贪婪的-它将一直匹配到最后,然后回溯到它可以匹配1,留下1010000000001.
.*?是非贪婪的。*将不匹配任何字符,但随后将尝试匹配额外的字符,直到匹配1,最终匹配101

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

在你的例子中,类似的模式可以是<([^>]*)> -匹配除大于号以外的任何字符(严格地说,它在<>之间匹配除>之外的零个或多个字符)。

看到量词小抄

贪婪vs非贪婪

regex中的重复在默认情况下是贪婪的:它们尝试匹配尽可能多的代表,当这不起作用时,它们必须回溯,它们尝试一次匹配更少的代表,直到找到整个模式的匹配。因此,当匹配最终发生时,贪婪重复将匹配尽可能多的许多次。

作为重复量词的?将此行为更改为贪婪的,,也称为不情愿的 (用Java语言)(有时也称为“lazy”)。相比之下,这种重复将首先尝试匹配次,当这不起作用时,他们必须返回,他们开始匹配一次更多的报告。因此,当匹配最终发生时,不情愿的重复将匹配尽可能多的次。

参考文献


例1:从A到Z

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

给定以下输入:

eeeAiiZuuuuAoooZeeee

这些模式产生以下匹配项:

让我们首先关注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中的不情愿重复首先匹配尽可能少的.,然后根据需要匹配更多的.。这解释了为什么它在输入中找到两个匹配项。

下面是两种模式匹配的视觉表现:

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

示例:替代方案

在许多应用程序中,上述输入中的两个匹配是需要的,因此使用不情愿的.*?而不是贪婪的.*来防止过度匹配。然而,对于这个特定的模式,有一个更好的选择,使用反字符类。

模式A[^Z]*Z也为上面的输入(在ideone.com上可以看到)找到了与A.*?Z模式相同的两个匹配项。[^Z]是所谓的否定字符类:它匹配除Z以外的任何东西。

这两种模式之间的主要区别在于性能:更严格地说,对于给定的输入,负字符类只能匹配一种方式。对于这种模式,使用贪婪修饰符还是不情愿修饰符都没有关系。事实上,在某些情况下,你甚至可以做得更好,使用所谓的所有格量词,这根本不会回溯。

参考文献


例2:从A到ZZ

这个例子应该是说明性的:它展示了给定相同的输入,贪婪、不情愿和否定字符类模式如何不同地匹配。

eeAiiZooAuuZZeeeZZfff

这些是上面输入的匹配项:

下面是他们匹配的视觉表现:

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

相关的话题

这些链接指向stackoverflow上的问题和答案,涵盖了一些可能感兴趣的主题。

一个贪婪的重复可以outgreed另一个