RegExp.protoype.test返回令人困惑的结果

时间:2016-01-07 03:37:58

标签: javascript regex

我不理解以下JavaScript的结果:

const reg = new RegExp(/@test1|@test2|@test3|@test4|@test5|@test6/g)

reg.test('normal text'); // false
reg.test('@test1');      // true
reg.test('@test2');      // false
reg.test('@test3');      // true
reg.test('@test4');      // false
reg.test('@test5');      // true
reg.test('@test6');      // false

真正奇怪的是,你调用的顺序无关紧要(b)通过测试(g)结果总是一样的......为什么???

1 个答案:

答案 0 :(得分:2)

来自RegExp.lastIndex

的MDN文档
  

lastIndex是正则表达式的读/写整数属性,指定开始下一个匹配的索引。

     

说明

     

仅当正则表达式使用“g”标志指示全局搜索时才设置此属性。以下规则适用:

     
      
  • 如果lastIndex大于字符串的长度,test()exec()失败,则lastIndex设置为0.
  •   
  • 如果lastIndex等于字符串的长度,并且正则表达式与空字符串匹配,那么常规   表达式匹配从lastIndex开始的输入。
  •   
  • 如果lastIndex等于字符串的长度,并且正则表达式与空字符串不匹配,那么常规   表达式不匹配输入,lastIndex重置为0.
  •   
  • 否则,lastIndex将设置为最近一次匹配后的下一个位置。
  •   

执行第一个test时,lastIndex设置为字符串的结尾。下次使用正则表达式时,它将从字符串的结尾开始搜索 (规则#2)并且它会失败,因此test()将返回false。之后,从上述声明(规则#1)开始,lastIndex设置为0,下一个test()将返回true

var reg = new RegExp(/@test1|@test2|@test3|@test4|@test5|@test6/g);

console.log(reg.test('normal text'));
console.log(reg.lastIndex);

console.log(reg.test('@test1'));
console.log(reg.lastIndex);

console.log(reg.test('@test2'));
console.log(reg.lastIndex);

console.log(reg.test('@test3'));
console.log(reg.lastIndex);

使用RegExp#test时,使用g标识符/标记时,简单规则是test只检查模式的存在,你不要需要g

const reg = new RegExp(/@test1|@test2|@test3|@test4|@test5|@test6/);

console.log(reg.test('normal text'));
console.log(reg.lastIndex);

console.log(reg.test('@test1'));
console.log(reg.lastIndex);

console.log(reg.test('@test2'));
console.log(reg.lastIndex);

如果您仍想使用g标记:不知道原因),则lastIndex属性可以设置为0从字符串的开头开始匹配。

使用此内循环时要小心。

var reg = new RegExp(/@test1|@test2|@test3|@test4|@test5|@test6/g);

console.log(reg.test('normal text'));
reg.lastIndex = 0;

console.log(reg.test('@test1'));
reg.lastIndex = 0;

console.log(reg.test('@test2'));
reg.lastIndex = 0;

console.log(reg.test('@test3'));
reg.lastIndex = 0;

这是相同的正则表达式,通过取出公共部分并使用OR条件

来编写
/@test(1|2|3|4|5|6)/

OR

/@test[1-6]/

因为,RegExp构造函数接受字符串,反斜杠需要双重转义。我建议使用正则表达式文字形式。