使用 Ruby 正则表达式,我得到了以下结果:
>> 'foobar'[/o+/]
=> "oo"
>> 'foobar'[/o*/]
=> ""
但是:
>> 'foobar'[/fo+/]
=> "foo"
>> 'foobar'[/fo*/]
=> "foo"
文档说明如下:
*: 前面的字符重复零次或更多次
+: 前面的字符重复一次或更多次
因此,我期望'foobar'[/o*/]和'foobar'[/o+/]返回相同的结果。
有人能解释一下吗?
'foobar'[/o*/]
匹配的是在位置0出现在 f
前面的零个 o
,而 'foobar'[/o+/]
无法匹配此处,因为至少需要有1个o
,所以它会匹配从位置1开始的所有o
。'foobar'[/o*/]
=>
'<>foobar'
'foobar'[/o+/]
=>
'f<oo>bar'
这是对正则表达式工作原理的一个常见误解。
虽然 * 是贪婪的,而且没有锚定在字符串的开头,但正则表达式引擎仍然会从字符串的开头开始查找。在 "/o+/" 的情况下,它不匹配位置 0(例如 "f"),但由于 + 表示一个或多个,它必须继续匹配(这与贪婪无关)直到找到匹配项或评估所有位置。
然而,在 "/o*/" 的情况下,你知道它表示 0 次或多次,当它不在位置 0 匹配时,正则表达式引擎将优雅地停止在那一点(因为 o* 只是表示 o 是可选的)。还有性能原因,因为 "o" 是可选的,为什么要花更多时间寻找它呢?