Js正则多次调用test()返回结果不同问题

正则表达式的标志(global全局匹配)/g导致的,RegExp有一个lastIndex属性,而全局标识会影响lastIndex属性,导致每次匹配都从上次匹配的位置开始,这就可能导致不符合预期的行为了。

问题出现

看代码

1
2
3
4
5
6
7
let pattern = /^(?=.*[a-zA-Z])(?=.*\d)[a-zA-Z\d!@#$%^&*()_+]$/g
let value = "abc123"

/* 可恶啊。。。这里执行一遍之后居然会改变后面的状态 */
console.log("1:", pattern.test(value));
console.log("2:", pattern.test(value));

控制台输出

1
2
3
/* 返回 */
1: true
2: false

这里可以看到我们第一次console的时候返回的的是true是正确的,那么第二次console的是时候却变成了false,之后不管console多少次都是false,所以如果我们多次利用pattern.test()的话是会出现判断

问题原因

这是因为正则表达式的标志(global全局匹配)/g导致的,RegExp有一个lastIndex属性,而全局标识会影响lastIndex属性,导致每次匹配都从上次匹配的位置开始,这就可能导致不符合预期的行为了。

解决方案

  • 去除全局标准/g:最简单的方法就是不使用全局标志/g
  • 重置lastIndex属性:每次调用完test()的时候将lastIndex重置为零,确保下次匹配都从字符串的开头开始。
    1
    2
    3
    console.log("1:", pattern.test(value));
    pattern.lastIndex = 0;
    console.log("2:", pattern.test(value));
    输出结果:
    1
    2
    3
    /* 返回 */
    1: true
    2: true

Js正则多次调用test()返回结果不同问题
http://example.com/2023/10/10/Js正则多次调用test-返回结果不同问题/
作者
Mr.H
发布于
2023年10月10日
许可协议