今天朋友问我一个问题,我如今须要屡次匹配同一个内容,可是为何我第一次匹配,直接是 true,而第二次匹配确实 false 呢?html
var s1 = "MRLP"; var s2 = "MRLP"; var reg = /mrlp/ig; console.log(reg.test(s1)); console.log(reg.test(s2));
这时候你会发现,咱们在连续使用一个正则匹配其余字符串的时候,第一次匹配是 true,而第二次匹配则是 false。正则表达式
等等,WHT?我匹配的是 MRLP,并且我还特地加上i
用于不区分大小写,能够为何第一次能够正常匹配,第二次就不行了呢?数组
这也就是我今天要跟你们说的,关于 JS 中的 lastIndex。函数
2. lastIndex
在开始讲解以前,首先先带你们简单回顾一下 JS中正则表达式的使用方式。post
JS 中正则表达式的使用方式有两种:this
第一种是正则表达式对象的方法,经常使用方法有两个。spa
- exec(str) : 检索字符串中指定的值。返回找到的值,并肯定其位置
- test(str) : 检索字符串中指定的值。返回 true 或 false
第二种是字符串对象的方法,经常使用方法有四个。code
- match(regexp) : 找到一个或多个正则表达式的匹配,返回一个配配的数组(该数组的内容依赖于 regexp 是否具备全局标志 g。)
- replace(regexp/substr,replacement) : 替换与正则表达式匹配的子串,返回一个新的字符串(replacement能够是字符串或函数、lambda表达式)
- search(regexp) : 检索与正则表达式相匹配的值,返回相匹配的子串的起始位置,不然返回 -1。(它将忽略标志g和 lastIndex属性,且老是从字符串的开始处进行检索)
- split(search) : 把字符串根据正则匹配的字符,分割为字符串数组,返回数组
参考:https://www.w3school.com.cn/jsref/jsref_obj_string.asp
regexp
而这些方法和我们今天所说的 lastIndex 有什么关系呢?htm
lastIndex 属性用于规定下次匹配的起始位置。
上次匹配的结果是由方法 RegExp.exec( )
和 RegExp.test( )
找到的,它们都以 lastIndex 属性所指的位置做为下次检索的起始点。
这样,就能够经过反复调用这两个方法来遍历一个字符串中的全部匹配文本。
并且须要注意,该属性只有设置标志 g才能使用。
既然已经知道这个东西的造成缘由,那么解决起来就很是简单了。
3.解决方案
3.1 第一种解决方案
如上面所述,咱们 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
3.2 第二种解决方案
不少时候,咱们必需要执行 全局匹配( 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