今天在写一个循环里面,通过正则方法test()来验证字符串,遇到了一个坑。在此分享一下采坑过程,也给自己加深个印象。
贴上我的一部分代码:
var str1 = '我是在测试';
var p = /[\u4E00-\u9FA5]/g; //匹配中文正则
var arr = str1.split('');
for(var i = 0; i < arr.length; i++) {
var isB = p.test(arr[i])
console.log(isB)
}
我这里的正则表达式p
,是用来匹配中文字符,若为中文字符则输出true
。所以讲道理的话,这个for
循环输出的应该全都是true
,但是现实都是残酷的。
结果是:
纳尼?怎么是true
和false
交替输出?
是时候lastIndex
出场了,从字面的意思是最后一个索引。它的真正意思是针对正则对象的方法,如果exec()
、test()
。用这些方法进行全局匹配时(/ /g
),当匹配成功时,该索引(lastIndex
的值)就指向了匹配成功的字符索引,下次再进行匹配时,则从lastIndex
记录的位置继续进行匹配,倘若没有匹配成功,lastIndex
则重置为0。
因此我们来针对这个循环来分析下:
第一次循环:
i = 0
,正则对象的lastIndex = 0
;因此p.test(arr[0])
,arr[0]
的值是“我”
,是汉字为true
,没毛病。但是此时要注意了,因为我们用的是全局匹配,并且用的是正则对象的方法test()
。所以此时的lastIndex
是等于1了。
第二次循环:
i = 1
,此时的p.test(arr[1])
,这里arr[1]
的值是"是"
。有同学会说不也还是汉字么,就怎么TMD为false
呢。注意,lastIndex
的值是为1,因此正则开始匹配的位置如下图:
明白了吗?因此false
!!!然后再将 lastIndex
重置为0,以下的循环就这样交替输出。