var reg1 = /^1$/g;
var reg2 = /^1$/;
for (var i = 0; i < 10; i++) {
console.log(reg1.test('1')) // true false true false true false true false ...
console.log(/^1$/g.test('1')) // true true true true true true true ...
console.log(reg2.test('1')) // true true true true true true true ...
console.log(/^1$/.test('1')) // true true true true true true true ...
}
为什么第一条console.log的输出会是这样?
正则执行时, RegExp对象的lastIndex可能会改变.
test 方法用于检测一个字符串是否匹配某个正则规则, 只要是字符串中含有与正则规则匹配的文本, 该方法就返回true, 否则返回 false.
实际上, 如果正则表达式带有全局标志(带有参数g)时, test 方法还受正则对象的lastIndex属性影响,如下:
该影响将在exec 方法讲解中予以分析.
exec 方法用于检测字符串对正则表达式的匹配, 如果找到了匹配的文本, 则返回一个结果数组, 否则返回null.
语法: exec(string)
exec 方法返回的数组中包含两个额外的属性, index 和 input. 并且该数组具有如下特点:
第 0 个项表示正则表达式捕获的文本
第 1~n 项表示第 1~n 个反向引用, 依次指向第 1~n 个分组捕获的文本, 可以使用RegExp.$ + "编号1~n" 依次获取分组中的文本
index 表示匹配字符串的初始位置
input 表示正在检索的字符串
无论正则表达式有无全局标示"g", exec 的表现都相同. 但正则表达式对象的表现却有些不同. 下面我们来详细说明下正则表达式对象的表现都有哪些不同.
假设正则表达式对象为 reg , 检测的字符为 string , reg.exec(string) 返回值为 array.
若 reg 包含全局标示"g", 那么 reg.lastIndex 属性表示原字符串中匹配的字符串末尾的后一个位置, 即下次匹配开始的位置, 此时 reg.lastIndex == array.index(匹配开始的位置) + array[0].length(匹配字符串的长度). 如下:
随着检索继续, array.index 的值将往后递增, 也就是说, reg.lastIndex 的值也会同步往后递增. 因此, 我们也可以通过反复调用 exec 方法来遍历字符串中所有的匹配文本. 直到 exec 方法再也匹配不到文本时, 它将返回 null, 并把 reg.lastIndex 属性重置为 0.
接着上述例子, 我们继续执行代码, 看看上面说的对不对, 如下所示:
以上代码中, 随着反复调用 exec 方法, reg.lastIndex 属性最终被重置为 0.
问题回顾
在 test 方法的讲解中, 我们留下了一个问题. 如果正则表达式带有全局标志g, 以上 test 方法的执行结果将受 reg.lastIndex影响, 不仅如此, exec 方法也一样. 由于 reg.lastIndex 的值并不总是为零, 并且它决定了下次匹配开始的位置, 如果在一个字符串中完成了一次匹配之后要开始检索新的字符串, 那就必须要手动地把 lastIndex 属性重置为 0. 避免出现下面这种错误:
以上代码, 正确执行结果应该是 "123456", 因此建议在第二次执行 exec 方法前, 增加一句 "reg.lastIndex = 0;".
若 reg 不包含全局标示"g", 那么 exec 方法的执行结果(array)将与 string.match(reg) 方法执行结果完全相同.
该片段来自 正则表达式前端使用手册 | louis blog 有帮助的话请点个赞吧~