正则前瞻匹配困惑:为何'mA11'不匹配组合前瞻规则?
正则匹配问题解答
先看你提供的代码及输出:
let sampleWord = "mA11"; let match1 = /(?=\w{4,6})(?=\D\d{2})/; let match2 = /(?=\w{4,6})/; let match3 = /(?=\D\d{2})/; console.log(match1.test(sampleWord)); console.log(match2.test(sampleWord)); console.log(match3.test(sampleWord));
输出:
false true true
问题1:为什么'mA11'不匹配/(?=\w{4,6})(?=\D\d{2})/
多个正向前瞻是针对同一个匹配位置同时生效的,而非分别独立检查整个字符串。
拆解两个前瞻的要求:
(?=\w{4,6}):要求从当前匹配位置开始,后面紧跟着4-6个\w(字母、数字、下划线)字符;(?=\D\d{2}):要求从当前匹配位置开始,后面第一个字符是非数字,紧接着两个连续数字。
分析'mA11'的所有可能匹配位置:
- 位置0(字符串开头):满足第一个前瞻(后面有4个
\w),但第二个前瞻不满足——位置0后第一个字符是m(非数字),但第二个字符是A(也是非数字),无法形成\D\d{2}; - 位置1及之后:后面剩余的字符数不足4个,无法满足第一个前瞻的
\w{4,6}要求。
没有任何一个位置能同时满足两个前瞻,所以match1.test(sampleWord)返回false。
问题2:为什么'mA111'能匹配match1,长于6位的字符串也能匹配
还是基于前瞻的工作逻辑:
对于'mA111'(长度5),在位置1(字符
A的位置):- 后面跟着
A111,共4个\w字符,满足(?=\w{4,6}); - 位置1后第一个字符是
A(非数字),紧接着是11,刚好符合\D\d{2},满足第二个前瞻。
两个条件同时满足,所以匹配成功。
- 后面跟着
对于长于6位的字符串(比如'mA111111a',长度7):
- 同样在位置1,后面跟着的字符中,前6个都是
\w,满足(?=\w{4,6})(只要存在4-6个连续\w即可,不需要刚好到字符串结尾); - 位置1后的
A11也符合\D\d{2},满足第二个前瞻。
因此依然能匹配成功。
- 同样在位置1,后面跟着的字符中,前6个都是
另外要注意:你的正则没有使用^(开头锚定)和$(结尾锚定),所以不会限制整个字符串的长度,只要字符串中存在某个位置满足两个前瞻的要求,就会返回true。
内容的提问来源于stack exchange,提问作者NobinPegasus
相关产品推荐
相关产品推荐

