正則屢次匹配無效的問題

引子

檢測一批手機號碼是否都符合要求的格式,循環用正則校驗,發現無效。去查找了下資料,發現了以前沒有注意到地方。git

問題

下面是問題重現: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 處開始匹配字符串。

驗證一下:ide

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 ,再想想這個場景下沒有必要使用全局匹配。ui

方法 2

使用 String.prototype.search()prototype

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

方法 3

每次循環匹配的時候,從新聲明一個正則。code

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

參考資料

相關文章
相關標籤/搜索