前言:
一开始一个朋友发消息问我:
var a = ['123.JpG','123.jpg'];
var reg = /(jpg|png)$/ig;
a.forEach(v => {
if(reg.test(v) === true){
console.log(123)
}
})
会输出什么。
我理所当然的说,当然是输出两个123
了。
lastIndex:
这时候你会发现,我们在连续使用一个正则匹配其他字符串的时候,第一次匹配是 true,而第二次匹配则是 false。
查看了一下 MDN文档 发现这样一个描述:
如果正则表达式设置了全局标志,test() 的执行会改变正则表达式 lastIndex属性。连续的执行test()方法,后续的执行将会从 lastIndex 处开始匹配字符串,(exec() 同样改变正则本身的 lastIndex属性值).
解决方案:
- 方案1
既然文档说了是因为
全局标志
才会影响到lastIndex
,于是可以把g
去掉就可以了。
var reg = /(jpg|png)$/i;
console.log(reg.test(a[0])); //true
console.log(reg.test(a[0])); //true
- 方案2
有时候既然需要用到
g
,那就不能用到方案1的方法了。 其实,我们的lastIndex
属性是可读可写的。 我们可以在下一次匹配的之前更改lastIndex
的值来达到目的:
var reg = /(jpg|png)$/ig;
console.log(reg.test(a[0])); //true
console.log(reg.lastIndex); //7
reg.lastIndex = 0;
console.log(reg.test(a[0])); //true
最后:
再来回顾最开始的问题,我们只需要选择方案1或者方案2中的一个方法,即可实现输出两个123
: