2011-07-18 5 views
10

私は一日中この問題に取り組んできました。何か間違っているのか、ChromeのJavaScriptエンジンにバグが見つかったのか分かりません。グローバルフラグを持つRegExpオブジェクトへの連続した呼び出しは、同じ入力文字列に対して一貫性のない結果を返すようです。私は、次の機能をテストしています:RegExpテストへの連続呼び出しがグローバルオプションのパターンで失敗する

function testRegex(pattern, array) { 
    document.writeln('Pattern = ' + pattern + ', Array = ' + array + '<br/>'); 
    for (var ii = 0; ii < array.length; ii++) { 
     document.writeln(ii + ', '); 
     document.writeln(array[ii] + ', '); 
     document.writeln(pattern.test(array[ii]) + '<br />'); 
    } 
    document.writeln('<br/>'); 
} 

私は、パターンと文字列の様々な配列として/a/gで関数を呼び出すと、私は私の知る限り間違っているその多くは次のような結果を取得します:

// EXPECTED: True 
// ACTUAL: True 
testRegex(/a/g, ['a']); 

// EXPECTED: True, True 
// ACTUAL: True, False 
testRegex(/a/g, ['a', 'a']); 

// EXPECTED: True, True, True 
// ACTUAL: True, False, True 
testRegex(/a/g, ['a', 'a', 'a']); 

// EXPECTED: True, False, True 
// ACTUAL: True, False, True 
testRegex(/a/g, ['a', 'b', 'a']); 

// EXPECTED: True, True, True, True 
// ACTUAL: True, False, True, False 
testRegex(/a/g, ['a', 'a', 'a', 'a']); 

// EXPECTED: True, False, False, True 
// ACTUAL: True, False, False, True 
testRegex(/a/g, ['a', 'b', 'b', 'a']); 

Iは、文字列の同一のアレイと同じ関数呼び出しが、パターンとして/a/を渡す

は、実際の結果はすべて、期待される結果と一致します。

// EXPECTED: True 
// ACTUAL: True 
testRegex(/a/, ['a']); 

// EXPECTED: True, True 
// ACTUAL: True, True 
testRegex(/a/, ['a', 'a']); 

// EXPECTED: True, True, True 
// ACTUAL: True, True, True 
testRegex(/a/, ['a', 'a', 'a']); 

// EXPECTED: True, False, True 
// ACTUAL: True, False, True 
testRegex(/a/, ['a', 'b', 'a']); 

// EXPECTED: True, True, True, True 
// ACTUAL: True, True, True, True 
testRegex(/a/, ['a', 'a', 'a', 'a']); 

// EXPECTED: True, False, False, True 
// ACTUAL: True, False, False, True 
testRegex(/a/, ['a', 'b', 'b', 'a']); 

私は上記のコードの作業例を作成しました:http://jsfiddle.net/FishBasketGordo/gBWsN/

私は何かが足りないのですか?パターンがグローバルかどうかに関係なく、指定された文字列の配列の結果が同じではないでしょうか?その後

for (var ii = 0; ii < array.length; ii++) { 
    document.writeln(ii + ', '); 
    document.writeln(array[ii] + ', '); 
    document.writeln(pattern.test(array[ii]) + '<br />'); 
    pattern.lastIndex = 0; 
} 

あなたのコードになります。注、私は主にChromeで働いてきましたが、次のように、あなたのテストループを変更した場合、私は、Firefox 4とIE 8

答えて

15

に同様の誤った結果を観察してきました作業。問題は、 "g"フラグがRegExpオブジェクトにスタックする原因になっていることです。 "lastIndex"値は、 "g"のために、そのループの最初の反復後に1に設定されます。検索をリセットするためにそれを設定しないと、2番目の呼び出しで、オフセット1から継続することを要求しているとみなされます。

コンテキスト外の正規表現で「g」フラグを使用するとにかく ".replace()"呼び出しには奇妙な意味があります。

+0

私の目標今朝始め、私はそもそもグローバルオプションを使用していた理由である、最終的にreplace' 'で正規表現を使用することでしたが、私の正規表現のように、私は中間ステップに捕まってしまいました。 – FishBasketGordo

6

これはバグではなく機能です。あなたが得た結果は "間違った"ものではなく、予期せぬものだけです。

10.3.2。 RegExpインスタンスのプロパティ

各RegExpオブジェクトには5つのプロパティがあります。 sourceプロパティは、正規表現のテキストを含む読み取り専用の文字列です。グローバルプロパティは、正規表現にgフラグがあるかどうかを指定する読み取り専用ブール値です。 ignoreCaseプロパティーは、正規表現にiフラグがあるかどうかを指定する読み取り専用のブール値です。 multilineプロパティは、正規表現にmフラグがあるかどうかを指定する読み取り専用のブール値です。最後のプロパティは、読み書き整数のlastIndexです。 gフラグを含むパターンの場合、このプロパティは文字列に次の検索を開始する位置を格納します。これは、前のセクションで説明したように、exec()メソッドとtest()メソッドで使用されます。

Source

関連する問題