小心!正则 test() 匹配的一个“坑”

3,924 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第24天,点击查看活动详情


本瓜相信你一定经常用以下这种最最简单的正则来判断字符串中是否存在某个子字符(别说了,我就是)🐶

const pattern = /ab/g
pattern.test("abcd") // true

这样去匹配,有什么问题吗?

不急,现在来让你猜一下,以下代码的输出?

const pattern = /ab/g
console.log(pattern.test("abcd"))
console.log(pattern.test("abcd"))
console.log(pattern.test("abcd"))

“不就是三个 true 吗?!”

在控制台上打印试试?惊不惊喜、意不意外?

image.png

为什么是 true 、false 、true ?

原来这里,这里有个小坑需要注意下,用 test() 连续做匹配的时候,会出错,是因为一个我们将要认识的 —— 正则类型 lastIndex 属性!

lastIndex 属性用于规定下次匹配的起始位置。

每次当我们用正则 RegExp.exec() 和 RegExp.test() 进行匹配的时候,如果返回为 true,lastIndex 属性的值会发生变化,会变成正确匹配的子字符串的最后位置,并将此位置作为下次检索的起始点。如果返回为 false,lastIndex 重置为 0 ;

所以,我们这样打印试试就知道了:

const pattern = /ab/g
console.log(pattern.test("abcd")) // true
console.log(pattern.lastIndex) // 2
console.log(pattern.test("abcd")) // false
console.log(pattern.lastIndex) // 0
console.log(pattern.test("abcd")) // true
console.log(pattern.lastIndex) // 2

当我们第一次调用 pattern.test("abcd")pattern.lastIndex 为 2, 即字母 b 的位置,当再次调用 pattern.test("abcd") 则会从 b 的位置往后搜索,搜不到 ab 了,返回 false ,同时 lastIndex 重置为 0 ,然后第三次调用 pattern.test("abcd") 又能正确返回 true 了,lastIndex 也变成了 2。

不知道这个坑,你踩到过没?

image.png

怎么解决呢?

方法一:手动清理 lastIndex

const pattern = /ab/g
console.log(pattern.test("abcd")) // true
pattern.lastIndex = 0
console.log(pattern.test("abcd")) // true

不过,这样手动清理很麻烦,显得很笨,所以建议用方法二。

方法二:用 match 来匹配

const pattern = /ab/g
console.log("abcd".match(pattern)) // ['ab']
console.log("abcdab".match(pattern)) // ['ab', 'ab']
console.log("123".match(pattern)) // null

match 是匹配的更优解,不用手动清理,存在则悉数返回成数组,不存在,返回 null

image.png


OK,以上便是本篇分享。点赞关注评论,为好文助力👍

我是掘金安东尼 🤠 100 万阅读量人气前端技术博主 💥 INFP 写作人格坚持 1000 日更文 ✍ 关注我,陪你一起度过漫长编程岁月 🌏