2009-03-03 46 views
8

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

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)); 

我得到了一个'真',后面跟着'假',然后是'真',然后是'假'。如果我使用循环来执行它,我发现了一些更有趣的东西,我在IE和Safari中获得了四个“真实”,在FF和Chrome中获得了true,false,true和false。

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的正则表达式的行为就像是什么原因浏览器返回不同的结果? (与变量声明和生命范围有关?)

回答

19

当您在JS RegExp上使用全局标志时,“test”和“exec”方法每次在第一次匹配时暂停,但保留一个指向它们停止在串。该指针可以在lastIndex属性上检查。当您再次拨打“测试”或“执行”时,它会开始搜索从lastIndex开始的比赛。

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

MDC具有此行为的decent explanation

+0

非常感谢,在MDC的交代很清楚。 – Darkthread 2009-03-03 03:08:06

0

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

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

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)); 

全局(克)平设置属性RegExp.lastIndex。所以每个测试()都会从最后一个停止的地方开始。

欲了解更多信息请参见文档中关于RegExp.lastIndex