Ruby正则表达式:+和*的特殊行为?

7

使用 Ruby 正则表达式,我得到了以下结果:

>> 'foobar'[/o+/]
=> "oo"
>> 'foobar'[/o*/]
=> ""

但是:

>> 'foobar'[/fo+/]
=> "foo"
>> 'foobar'[/fo*/]
=> "foo"

文档说明如下:
*: 前面的字符重复零次或更多次
+: 前面的字符重复一次或更多次

因此,我期望'foobar'[/o*/]和'foobar'[/o+/]返回相同的结果。

有人能解释一下吗?

2个回答

14
'foobar'[/o*/] 匹配的是在位置0出现在 f 前面的零个 o,而 'foobar'[/o+/] 无法匹配此处,因为至少需要有1个o,所以它会匹配从位置1开始的所有o
具体来说,您看到的匹配项如下: 'foobar'[/o*/] => '<>foobar'
'foobar'[/o+/] => 'f<oo>bar'

3

这是对正则表达式工作原理的一个常见误解。

虽然 * 是贪婪的,而且没有锚定在字符串的开头,但正则表达式引擎仍然会从字符串的开头开始查找。在 "/o+/" 的情况下,它不匹配位置 0(例如 "f"),但由于 + 表示一个或多个,它必须继续匹配(这与贪婪无关)直到找到匹配项或评估所有位置。

然而,在 "/o*/" 的情况下,你知道它表示 0 次或多次,当它不在位置 0 匹配时,正则表达式引擎将优雅地停止在那一点(因为 o* 只是表示 o 是可选的)。还有性能原因,因为 "o" 是可选的,为什么要花更多时间寻找它呢?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接