RegExp.test() 方法使用全局匹配时一会返回 true 一会返回 false ?

作者站长头像
站长
· 阅读数 5

问题描述

在使用 RegExp.test() 方法时使用 g 全局匹配时会依次返回 truefalse

问题出现的环境背景及自己尝试过哪些方法

一开始以为是正则写的不对,把其它的匹配规则都去掉有试了试,结果问题还是依旧。没有覆写的 .test() 方法,使用空白页测试,依旧有这样的问题。

相关代码

var t = /#/g
t.test("#")
// true
t.test("#")
// false
t.test("#")
// true
t.test("#")
// false

你期待的结果是什么?实际看到的错误信息又是什么?

为什么会一次返回 truefalse,而不是固定的一个结果?


本文参与了SegmentFault 思否面试闯关挑战赛,欢迎正在阅读的你也加入。
回复
1个回答
avatar
test
2024-07-07

正则表达式使用 g 全局检索时会内置一个 lastIndex 属性,并且这个属性并不会被重置,会在下一次使用时保留(如果 index 值小于或等于字符串长度时)在 MDN 文档上面也提到了这个问题 Using test() on a regex with the “global” flag


所以可以通过每次调用后重置掉 lastIndex 值,比如说:

var t = /#/g
t.test("#")
// true
t.lastIndex = 0
t.test("#")
// true
t.lastIndex = 0
t.test("#")
// true
t.lastIndex = 0

但是很不优雅,可以使每次一都使用新的正则,或者封装在一个方法内来避免,例如:

/#/g.test("#")
// true
/#/g.test("#")
// true
/#/g.test("#")
// true

或者

function fn(str){
  const regex = /#/g
  return regex.test(str)
}
fn("#")
// true
fn("#")
// true
fn("#")
// true

其实直接去掉 g 全局匹配的标识就可以了,因为大部分的时间只是想要去测试一下字符串是否匹配预设规则而已。

本文参与了SegmentFault 思否面试闯关挑战赛,欢迎正在阅读的你也加入。
回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容