我想写一个匹配
的正则表达式a
a-b
但仅限于这些序列后面没有Z
((a(-b)?)(?!Z))
a matches a ok
a-b matches a-b ok
aZ empty ok
a-bZ matches a NOT OK
为什么“a-bZ”与第一个a匹配,尽管周围有一组(a(-b)?)? 我该如何纠正?
在javascript RegExp中需要这个,但这应该不重要。在http://regexpal.com/
中尝试过答案 0 :(得分:4)
a-bZ
,因为(-b)?
被忽略且(?!Z)
与-
符号匹配。
由于(-b)
是可选的,因此((a)(?!Z))
形式的每个字符串也会匹配。
您可以匹配(a(?!Z))|(a-b(?!Z))
但是,这将匹配a-bZ
(因为a后跟非Z字符)。
如果你想查找字符串的所有实例,例如,a-c
没有匹配(即使-
是非Z字符),你可以这样做:
(a(?![-Z]))|(a-b(?!Z))
答案 1 :(得分:2)
您可以使用原子分组来使您的正则表达式工作。不幸的是,JavaScript正则表达式引擎不支持此功能。
但是使用前瞻和后引用(explained here)模仿其效果有一个技巧:
(?=(pattern to make atomic))\1
因此,对于您的a-b
或a
情况,这将成为:
(?=(a-b|a))\1(?!Z)
请注意,需要首先在组中提及较长的子模式a-b
,否则它不起作用。
关键机制是前瞻找到最早,最长可能的子匹配,而后引用阻止引擎中的任何回溯并移动字符串中的位置,因此以下测试{{1}可以执行。
答案 2 :(得分:1)
如果指定起始锚点和结束锚点,则上述正则表达式((a(-b)?)(?!Z))
与字符串a-bZ
不匹配,请参阅演示here。由于未指定锚点且(-b)
是可选的,因此正则表达式引擎首先尝试将a-b
匹配,然后在看到以下Z
字母时丢弃匹配项。现在,由于可选-b
得到匹配,正则表达式引擎回溯。现在它位于a
,a
字母后面没有紧跟Z
,因此引擎现在匹配字母a