首先,要明确一点,所有的正则表达式都有一个lastIndex
属性,用于记录上一次匹配结束的位置。如果不是全局匹配模式,那lastIndex
的值始终为0,在匹配过一次后,将会停止匹配。
正则表达式的全局匹配模式,就是在创建正则表达式的时候使用g
标识符或者将global
属性设置为true
,在全局匹配模式下,正则表达式会对指定要查找的字符串执行多次匹配。每次匹配使用当前正则对象的lastIndex
属性的值作为在目标字符串中开始查找的起始位置。如果找不到匹配的项lastIndex
的值会被重新设置为0
。
理解了上面的话,下面代码的结果就很清晰了:
var regex = /abc/g;
var str = '123#abc';
console.log(regex.lastIndex); // 0
console.log(regex.test(str)); // true
console.log(regex.lastIndex); // 7
console.log(regex.test(str)); // false
console.log(regex.lastIndex); // 0
console.log(regex.test(str)); // true
console.log(regex.lastIndex); // 7
console.log(regex.test(str)); // false
今天在写表单验证的时候遇到一个问题,每当偶数次点击的时候就会报错,就是这个问题造成的,解决方法也很简单,就是去掉正则表达式里面的g
。
关于RegExp.prototype.exec(str)
方法和String.prototype.math(rgExp)
方法:
RegExp.prototype.exec(str)
方法返回NULL
或返会一个数组,在数组的第0
个元素存放的是在字符串str
中查找到的匹配内容,1
到n
个元素返回的是在模式中使用括号"()
"指定的子匹配项的内容。
在没有使用全局标志时String.prototype.math(rgExp)
方法和RegExp.prototype.exec(str)
的行为类似。当设置了全局匹配标志时String.prototype.math(rgExp)
方法返回的数组项元素0
到n
中包含了所有匹配到的项不包含子匹配项。这时可以使用RegExp.$1..$9
获取9
个子匹配。
js正则表达式test()
方法
test()
方法是正则表达式的一个方法,用于检测一个字符串是否匹配某个模式.
test
方法检查字符串是否与给出的正则表达式模式相匹配,如果是则返回 true
,否则就返回 false
。
每个正则表达式都有一个lastIndex
属性,用于记录上一次匹配结束的位置.
语法:regexp.test(str)
在全局匹配模式下
对于同一个正则对象重复调用就会出现下一次的匹配位置从上一次匹配结束的位置开始,解决方法重置lastIndex
为0
let reg = /^[\d]{2}$/g;
let str = "12";
console.log(reg.test(str)); //返回true
let = "123";
console.log(reg.test(str)); //从数字3开始匹配,只有一个数字,故返回false
重置lastIndex
为0
let reg = /^[\d]{2}$/g;
let str = "12";
console.log(reg.test(str)); //返回true
let = "123";
reg.lastIndex = 0;
console.log(reg.test(str)); //返回true
在非全局匹配模式下,则不存在这个问题
let reg = /^[\d]{2}$/;
let str = "12";
console.log(reg.test(str)); //返回true
let = "123";
console.log(reg.test(str)); //返回true
另外,test()
方法和数组的forEach()
方法一起使用可能达不到预期结果,在for
循环下,同样如此,如下
let line = '1a 123 123 12';
let lines = line.split(' ');
let reg = /^[\d]+$/g;
let res = 0;
lines.forEach( function(element, index) {
console.log(reg.test(element)); // flase true 交替出现
});
使用forEach
方法对数组中字符串进行test
测试,会出现flase true
交替出现的现象,先出现false
还是true
则取决数组第一个元素匹配的结果。
同样的,在非全局匹配模式下,则不存在这个问题,这里去掉全局匹配g才可得到预期结果
let line = '1a 123 123 12'
let lines = line.split(' ');
let reg = /^[\d]+$/;
let res = 0;
lines.forEach( function(element, index) {
console.log(reg.test(element)); // false true true true
});