正则多次匹配无效的问题

Posted XXHolic

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了正则多次匹配无效的问题相关的知识,希望对你有一定的参考价值。

引子

检测一批手机号码是否都符合要求的格式,循环用正则校验,发现无效。去查找了下资料,发现了之前没有注意到地方。

  • Origin
  • My GitHub

问题

下面是问题重现:

const arr=[\'18311112222\',\'18344445555\',\'2857898098\']
const reg = /^1[3-9]\\d{9}$/g;
const result = arr.find(ele => !reg.test(ele));
console.info({result});

// {result: "18344445555"}

按照上面的正则,第二个号码符合要求,却返回了 false ,去查了资料,发现:

如果正则表达式设置了全局标志 gtest() 的执行会改变正则表达式 lastIndex 属性。连续的执行 test() 方法,后续的执行将会从 lastIndex 处开始匹配字符串。

验证一下:

const arr=[\'18311112222\',\'18344445555\',\'2857898098\']
const reg = /^1[3-9]\\d{9}$/g;
const result = arr.find(ele => {
  const lastIndex = reg.lastIndex;
  console.info({lastIndex});
  return !reg.test(ele);
});

// {lastIndex: 0}
// {lastIndex: 11}

解决方法

方法 1

去掉全局标志 g ,再想一想这个场景下没有必要使用全局匹配。

方法 2

使用 String.prototype.search() 。

const arr=[\'18311112222\',\'18344445555\',\'2857898098\']
const reg = /^1[3-9]\\d{9}$/g;
const result = arr.find(ele => ele.search(reg) === -1);

方法 3

每次循环匹配的时候,重新声明一个正则。

const arr=[\'18311112222\',\'18344445555\',\'2857898098\']
const result = arr.find(ele => {
  const reg = /^1[3-9]\\d{9}$/g;
  return !reg.test(ele);
});

参考资料

  • MDN Regular Expressions
  • MDN RegExp.prototype.test()
  • 正则表达式

以上是关于正则多次匹配无效的问题的主要内容,如果未能解决你的问题,请参考以下文章

循环通过 python 正则表达式匹配

正则表达式匹配特定的 URL 片段而不是所有其他 URL 可能性

如何使用正则表达式组查找多次出现?

多次匹配正则表达式模式

Javascript正则表达式量词:匹配零次或多次是啥意思

一个可以使用多个正则表达式进行多次尝试匹配,并进行替换的Excel VBA自定义函数(UFD)