正则表达式的顺序优先级
前言
假设存在匹配示例:匹配a-c@或a@
你认为正则a|(a-c)(?=\W)与(a-c)|a(?=\W)都能匹配上面的示例吗?这2个正则有什么本质区别?哪一个才是正确的写法?--这就涉及了正则表达式的顺序优先级,本文将解释这一点。
什么是正则表达式的顺序优先级呢?在正则表达式中,| 前后的表达式的顺序是有讲究的,如expression1|expression2和expression2|expression1匹配的结果或许存在不同,在编辑正则表达式时要有这样意识,否则编辑出的正则可能不符需求。
举例说明
示例1
源字符串:
a-c@
a@
正则表达式:
a|(a-c)(?=\W)
(a-c)|a(?=\W)
匹配结果:a|(a-c)(?=\W)能够匹配a@,但不能匹配a-c@;(a-c)|a(?=\W)则都可以匹配。
原因:(a-c)|a(?=\W)先匹配a-c这个整体,如果匹配失败则进行回溯,尝试匹配a,所以@前的a-c或a都是可匹配的;a|(a-c)(?=\W)能够匹配a@自不必说,但为什么不能匹配a-c@呢?因为它先匹配a,剩下-c@,-匹配(?=\W)成功,整个正则匹配成功,匹配结果为:a
示例2
源字符串:
1
01
11
正则表达式:
(0?[123456789]|(1[012]))
((1[012])|0?[123456789])
匹配结果:(0?[123456789]|(1[012]))可匹配1与01,不可匹配11;((1[012])|0?[123456789])可匹配所有的源字符串。
原因:同示例1。
小结
如本文开头所问,a|(a-c)(?=\W)与(a-c)|a(?=\W)的本质区别--后者的匹配广度高于前者,所以(a-c)|a(?=\W)才是符合需求的。