2009-03-03 7 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で4つの「真」が得られ、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プロパティで検査できます。 「test」または「exec」をもう一度呼び出すと、lastIndexから始まる一致が検索されます。

したがって、文字列全体に一致する文字列に対してRegExpをテストすると、lastIndexは文字列の最後に設定されます。次回のテストでは、文字列の最後で開始し、falseを返し、lastIndexをゼロに戻します。

MDCには、この動作のdecent explanationがあります。

+0

おかげで多くを見る、MDCの、について説明は非常に明確です。 – Darkthread

+0

+1それぞれのテストが私の問題を解決する前に、reg.lastIndex = 0に設定していただきありがとうございます。 – bendewey

+0

ループ内で問題が発生している場合は、各テストの前にlastIndex = 0に設定することができます。 – k0nG

0

これを回避するには、グローバル(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)); 

グローバル(G)フラットセットプロパティRegExp.lastIndex:

このコードは、出力すべきです。各テスト()は、最後のテストが停止した場所から開始されます。詳細情報については

は、マニュアルに関するRegExp.lastIndex

関連する問題