有趣的Javascript RegExp测试

时间:2009-03-03 02:18:19

标签: javascript regex

我写了一个Javascript RegExp测试来检测日期字符串格式,我错误地添加了一个冗余的“g”标志,发现了一些有趣的东西。

var s = "2009/03/10";
var regex=/^\d{4}[/]\d{2}[/]\d{2}$/g;
alert(regex.test(s));
alert(regex.test(s));
alert(regex.test(s));
alert(regex.test(s));

我得到'true'后面跟'false',然后是'true',然后是'false'。

如果我使用循环执行它,我发现更有趣的东西,我在IE和Safari中有四个“真实”,在FF,Chrome中有真,假,真,假。

for (var i=0; i<4; i++)
{
  var s = "2009/03/10";
  var regex=/^\d{4}[/]\d{2}[/]\d{2}$/g;
  alert(regex.test(s));
}

有没有人有想法解释为什么Javascript正则表达式会像这样,以及导致浏览器返回不同结果的原因是什么? (与变量声明和生命范围有关?)

2 个答案:

答案 0 :(得分:20)

当你在JS RegExp上使用全局标志时,“test”和“exec”方法在第一次匹配时都会停止,但保留一个指向它们停止在字符串中搜索的位置的指针。可以在lastIndex属性上检查该指针。当您再次呼叫“test”或“exec”时,它会开始搜索从lastIndex开始的匹配。

因此,当您在与整个字符串匹配的字符串上测试RegExp时,lastIndex将设置为字符串的结尾。下次测试时,从字符串末尾开始,返回false,并将lastIndex设置为零。

MDC有decent explanation这种行为。

答案 1 :(得分:0)

为避免这种奇怪的行为,请不要使用global(g)标志。

此代码应输出:'True','True','True','True'

var s = "2009/03/10";
var regex=/^\d{4}[/]\d{2}[/]\d{2}$/i;
alert(regex.test(s));
alert(regex.test(s));
alert(regex.test(s));
alert(regex.test(s));

global(g)flat设置属性RegExp.lastIndex。因此每个test()将从最后一个停止的地方开始。

有关详细信息,请参阅有关RegExp.lastIndex

的文档