问题
同一个正则表达式用了多次 返回的值一次是false一次true
var s1 = "MRLP";
var s2 = "MRLP";
var reg = /mrlp/ig;
console.log(reg.test(s1));// true
console.log(reg.test(s2));// false
lastIndex
在开始讲解之前,首先先带大家简单回顾一下 JS中正则表达式的使用方式。
JS 中正则表达式的使用方式有两种:
第一种是正则表达式对象的方法,常用方法有两个。
1、exec(str) : 检索字符串中指定的值。返回找到的值,并确定其位置
2、test(str) : 检索字符串中指定的值。返回 true 或 false 。
第二种是字符串对象的方法,常用方法有四个。
3、match(regexp) : 找到一个或多个正则表达式的匹配
4、replace(regexp) : 替换与正则表达式匹配的子串
5、search(regexp) : 检索与正则表达式相匹配的值
6、split(search) : 把字符串分割为字符串数组
而这些方法和咱们今天所说的 lastIndex 有什么关系呢?
lastIndex 属性用于规定下次匹配的起始位置。
上次匹配的结果是由方法 RegExp.exec( ) 和 RegExp.test( ) 找到的,它们都以 lastIndex 属性所指的位置作为下次检索的起始点。这样,就可以通过反复调用这两个方法来遍历一个字符串中的所有匹配文本。而且需要注意,该属性只有设置标志 g才能使用。
既然已经知道这个东西的形成原因,那么解决起来就非常简单了
解决方案
第一种解决方案
如上面所述,我们 lastIndex 属性必须要设置 g 标签才能使用。
那么我们在匹配的时候,可以根据情况,直接去掉 g 标签就可以啦。
var s1 = "MRLP";
var s2 = "MRLP";
var reg = /mrlp/i;
console.log(reg.test(s1)); //true
console.log(reg.test(s2)); //true
第二种解决方案
很多时候,我们必须要执行 全局匹配( g ),这时候就不能使用第一种方案了。
其实lastIndex 属性是可读可写的,只要目标字符串的下一次搜索开始,就可以对它进行设置。
当方法 exec() 或 test() 再也找不到可以匹配的文本时,它们会自动把 lastIndex 属性重置为 0。
这样,我们再次执行全局匹配的时候,就不会出现 false 的情况了。
var s1 = "3206064928:MRLP:3206064928";
var s2 = "MRLP";
var reg = /mrlp/ig;
console.log(reg.test(s1)); //true
console.log(reg.lastIndex); //reg.lastIndex = 15
reg.lastIndex = 0; //这里我将 lastIndex 重置为 0
console.log(reg.test(s2)); //true