今天我遇到了下面的正则表达式,想知道 Ruby 会用它做什么:
> "#a" =~ /^[\W].*+$/
=> 0
> "1a" =~ /^[\W].*+$/
=> nil
在这种情况下,Ruby 似乎忽略了 +
字符。如果这是不正确的,我不确定它在做什么。我猜它没有被解释为量词,因为 *
没有转义并且被用作量词。在 Perl/Ruby 正则表达式中,有时当一个字符(例如,-
)在不能被解释为特殊字符的上下文中使用时,它会被视为文字。但如果在这种情况下发生这种情况,我希望第一个匹配失败,因为左值字符串中没有 +
。
这是对 +
字符的巧妙正确使用吗?以上行为是错误吗?我是否遗漏了一些明显的东西?
最佳答案
当然,您可以在 *
之后使用 +
。您可以阅读一些相关信息 on this site . *
之后的+
称为所有格量词。
它有什么作用?它防止 *
回溯。
通常,当您有类似.*c
的内容并使用它来匹配abcde
时,.*
将首先匹配整个字符串(abcde
) 并且由于正则表达式无法匹配 .*
之后的 c
,引擎将一次返回一个字符以检查是否存在是一个匹配项(这是回溯)。
一旦回溯到c
,您将从abcde
获得匹配项abc
。
现在,假设引擎必须回溯几百个字符,如果您有嵌套组和多个 *
(或 +
或 {m ,n}
形式),您可以很快得到数千、数百万个要回溯的字符,称为 catastrophic backtracking .
这就是所有格量词派上用场的地方。他们实际上阻止了任何形式的回溯。在上面我提到的正则表达式中,abcde
不会被.*+c
匹配。一旦 .*+
消耗了整个字符串,它就无法回溯,并且由于字符串末尾没有 c
,所以匹配失败。
因此,所有格量词的另一种可能用途是它们可以提高某些正则表达式的性能,前提是引擎可以支持它。
对于您的正则表达式 /^[\W].*+$/
,我认为所有格量词没有提供任何改进(也许是一点点改进)。最后,它可能很容易被重写为 /^\W.*+$/
。
关于ruby - `+` 在 `*` 之后的含义,当后者在正则表达式中用作量词时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18971021/