6

今天我遇到了以下正则表达式,想知道 Ruby 会用它做什么:

> "#a" =~ /^[\W].*+$/
=> 0
> "1a" =~ /^[\W].*+$/
=> nil

在这种情况下,Ruby 似乎忽略了这个+角色。如果这是不正确的,我不确定它在做什么。我猜它没有被解释为量词,因为它*没有被转义并且被用作量词。在 Perl/Ruby 正则表达式中,有时当一个字符(例如-)在不能被解释为特殊字符的上下文中使用时,它被视为文字。但如果在这种情况下发生这种情况,我希望第一个匹配失败,因为+左值字符串中没有。

这是对+角色的巧妙正确使用吗?上述行为是错误吗?我错过了一些明显的东西吗?

4

1 回答 1

5

好吧,您当然可以在 a+之后使用 a *你可以在这个网站上读到一些关于它的信息。+后面的被*称为所有格量词。

它能做什么?它可以防止*回溯。

通常,当你有类似的东西.*c并使用它来匹配abcde时,.*将首先匹配整个字符串( ),并且由于正则表达式在 之后abcde无法匹配,引擎将一次返回一个字符以检查是否存在匹配(这是回溯)。c.*

一旦它回溯到c,您abc将从abcde.

现在,想象一下引擎必须回溯几百个字符,如果你有嵌套的组和多个*(或+{m,n}表单),你可以很快地回溯成千上万个字符,称为灾难性回溯

这就是所有格量词派上用场的地方。它们实际上阻止了任何形式的回溯。在我提到的上述正则表达式中,abcde不会被.*+c. 一旦.*+消耗了整个字符串,它就不能回溯,并且由于c字符串末尾没有 no,匹配失败。

因此,所有格量词的另一种可能用途是它们可以提高某些正则表达式的性能,前提是引擎可以支持它。

对于您的 regex /^[\W].*+$/,我不认为所有格量词提供了任何改进(也许是一点点改进)。最后,它可能很容易被重写为/^\W.*+$/.

于 2013-09-24T04:24:09.830 回答