考虑以下正则表达式:
(^.)?
如果可能,这匹配字符串开头的单个字符:
>> 'ab'.match(/(^.)?/)
Array [ "a", "a" ]
但是,将.
包裹在预测中会导致它停止工作:
>> 'ab'.match(/(^(?=.))?/)
Array [ "", undefined ]
undefined
的值表示该组不匹配,而不是匹配空字符串。但我不明白前瞻如何阻止群体匹配。我希望在这里获得["", ""]
的结果。
更奇怪的是,只有当周围的捕获组的宽度为0时才会出现这种情况。如果我们将^
锚更改为更长的时间,它会再次正常工作:
>> 'ab'.match(/(a(?=.))?/)
Array [ "a", "a" ]
删除使组成为可选的?
也会修复输出:
>> 'ab'.match(/(^(?=.))/)
Array [ "", "" ]
有人可以解释为什么会这样吗?这对我没有任何意义。
答案 0 :(得分:2)
这不需要涉及前瞻。任何以空匹配结束并且本身是可选的组都不匹配。
> /()/.exec('foo')
['', '']
> /()?/.exec('foo')
['', undefined]
这很奇怪,是的。
> /(.*?)/.exec('foo')
['', '']
> /(.*?)?/.exec('foo')
['f', 'f']
有a V8 test case表明行为是预期的。 This part of the spec
如果min为零且y的endIndex等于x的endIndex,则返回失败。
似乎相关但很难理解。如果它实际上导致了这里的行为(同时试图避免组匹配连续的空字符串?),我认为这是一个规范错误。其他语言的行为不一样。 (并非他们必须,但这是另一次罢工。)
实际上,the behaviour has been described before有关于在规范中解释的评论,但它实际上并非解释。 (有一个(a*)*
音符没有相应的输出,加上前面提到的步骤,没有任何理由提供,除了关于重复空匹配问题的其他一些说明,其他人似乎已经以更直观的方式解决了。)
>>> re.match(r'(.*?)?', 'foo').group(0, 1)
('', '')
> Dim m = Regex.Match("foo", "(.*?)?")
> m.Success
True
> m.Length
0
> 'foo' =~ /(.*?)?/
0
> $1
""
> 'foo' =~ /(.*?)?/
('')