问题:这是一个错误,还是我的误解?
这是一个接受“A red balloon”或“A blue balloon”的正则表达式,如node.js REP所示。我正在使用'非捕获'?:表单,因为我对捕获颜色不感兴趣:
/A (?:red)|(?:blue) balloon!/.exec("A red balloon!")
=> [ 'A red', index: 0, input: 'A red balloon!' ]
到目前为止,这么好。现在我希望匹配红色或蓝色“球”或“气球”或“弹道导弹”或诸如此类的东西并捕获:
/A (?:red)|(?:blue) (ba.+)!/.exec("A red ball bearing!")
=> [ 'A red', undefined, index: 0, input: 'A red ball bearing!' ]
匹配,但未能捕获第二种形式('滚珠轴承')。 (对于它的价值,regex101.com中的相同形式不匹配。)为了使其捕获,我必须将整个“或”子句包装在另一个非捕获括号中:
/A (?:(?:red)|(?:blue)) (ba.+)!/.exec("A red ball bearing!")
=> [ 'A red ball bearing!', 'ball bearing', index: 0, input: 'A red ball bearing!' ]
所以问题:为什么第二种形式不起作用? (或者为什么它在javascript中匹配而不在regex101.com中?)为什么引入另一个非捕获子句对后续捕获子句有任何影响?或者这表明存在错误?
答案 0 :(得分:1)
它将其解释为:
A (?:red)
要么
(?:blue) (ba.+)!
这就是它捕获的原因"红色"。一旦你添加了parantheses,它就被正确捕获了。它就像操作顺序一样。
随着parantheses,它变成了:
A
red OR blue
ba.+
!
答案 1 :(得分:0)
John Strom提供了正确的答案:归结为运算符优先级问题。可以在in the Microsoft Developer Network Library和其他地方找到运营商优先权的权威列表。总结从最高优先级('最严格的绑定')到最低优先级:
\
(逃脱)()
,(?:)
,(?=)
,[]
(括号和括号)*
,+
,?
,{n}
,{n,}
,{n,m}
(量词)^
,$
,\ anymetacharacter,anycharacter(Anchors and Sequences)|
(替代)正如MSDN文档所指出的那样:
字符的优先级高于交替运算符,允许
'm|food'
匹配"m"
或"food"
。要匹配"mood"
或"food"
,请使用括号创建子表达式,结果为'(m|f)ood'
。
因此原始示例可以更简单地编写为:
/A (?:red|blue) (ba.*)!/
...在javascript和regex101中正确检出。