Ruby a+;的含义在“*”之后,当后者在正则表达式中用作量词时
今天我遇到了以下正则表达式,我想知道Ruby将如何处理它:Ruby a+;的含义在“*”之后,当后者在正则表达式中用作量词时,ruby,regex,Ruby,Regex,今天我遇到了以下正则表达式,我想知道Ruby将如何处理它: > "#a" =~ /^[\W].*+$/ => 0 > "1a" =~ /^[\W].*+$/ => nil 在本例中,Ruby似乎忽略了+字符。如果这是错误的,我不知道它在用它做什么。我猜它没有被解释为量词,因为*没有转义,而是被用作量词。在Perl/Ruby正则表达式中,有时在不能将字符解释为特殊字符的上下文中使用字符(例如,-)时,会将其视为文本。但是如果在这种情况下发生这种情况,我希望第一次匹配失败,
> "#a" =~ /^[\W].*+$/
=> 0
> "1a" =~ /^[\W].*+$/
=> nil
在本例中,Ruby似乎忽略了+
字符。如果这是错误的,我不知道它在用它做什么。我猜它没有被解释为量词,因为*
没有转义,而是被用作量词。在Perl/Ruby正则表达式中,有时在不能将字符解释为特殊字符的上下文中使用字符(例如,-
)时,会将其视为文本。但是如果在这种情况下发生这种情况,我希望第一次匹配失败,因为左值字符串中没有+
这是
+
字符的微妙正确用法吗?上述行为是错误吗?我遗漏了一些明显的东西吗?好吧,你当然可以在*
之后使用+
。你可以读一些关于它的书。*
后面的+
称为所有格量词
它是干什么的?它防止*
回溯
通常,当您使用类似于*c
的内容来匹配abcde
时,*
将首先匹配整个字符串(abcde
),并且由于正则表达式在*
之后无法匹配c
,因此引擎将一次返回一个字符以检查是否存在匹配(这是回溯)
一旦它回溯到c
,您将从abcde
获得匹配的abc
现在,假设引擎必须回溯几百个字符,如果您有嵌套的组和多个*
(或+
或{m,n}
表单),您可以很快返回数千、数百万个字符,称为
这就是所有格量词派上用场的地方。它们实际上阻止了任何形式的回溯。在我提到的上述正则表达式中,abcde
将不会被*+c
匹配。一旦*+
消耗了整个字符串,它就无法回溯,因为字符串末尾没有c
,匹配失败
因此,所有格量词的另一个可能用途是,如果引擎能够支持,它们可以提高某些正则表达式的性能
对于您的正则表达式
/^[\W].+$/
,我认为没有任何改进(可能有一点点改进)不过,所有格量词提供了。最后,它可能很容易被重写为/^\W.*+$/
你在哪里遇到这个正则表达式的?在我工作过程中遇到的一些第三方安全内容中。我猜正则表达式不是作者想要的,但当我看到Ruby的行为时,我开始对它产生疑问t此假设。您可能得到的唯一改进是,引擎在进行匹配时不必保存中间状态。*
(稍后将用于回溯)。但该模式无论如何都不会回溯,因此在这方面没有任何节约。