2013-05-23 12 views
15

これはちょっとした問題ですが、私はそれをどのように修正できるか考えていますが、(もっと)簡単な方法があるのだろうかと思っています。JavaScriptのRegExpコンストラクタの汚染プロパティを防止する

つまり、JavaScriptで正規表現が実行されるたびに、特定のプロパティにRegExpコンストラクタの値が割り当てられます。例:

/foo/.test('football') 
//-> true 

RegExp.input 
//-> "football" 

RegExp.rightContext 
//-> "tball" 

これらのプロパティに影響することなく正規表現を実行したいと考えています。それが不可能であれば(そして私はそうではないと思う)、少なくとも私はそれを以前の値に戻したいと思っています。

私はinput/$_が書き込み可能だと知っていますが、他のほとんどはそうではありません。 1つの選択肢は、これらの値をすべて再適用する正規表現を再構築することですが、それはかなり難しいと思います。

私がshim of a native APIを書き、test262スイートを使ってテストしているからです。 test262スイートは、特定のテストで失敗し、RegExpオブジェクトにこれらのプロパティの予期しない値があるかどうかを確認します。

+0

これは一時的なものがありますか? –

+4

私はあなたが明らかにした謎を好きです。しかし、私の考えは、壊れた部分に対応するために変更する必要のないシステムの一部を変更しているということです。壊れた部分はテストフレームワークです。最終製品でRegExpオブジェクトが元の状態を保持する必要がない場合は、フレームワーク内の任意のテストでコードの書き換えを強制する必要はありません。変更したい部分がテストフレームワークであると私は思います。私はあなたがRegExpオブジェクトの特定のテストを無視するような設定オプションなどを探すと仮定しますか? –

+0

@ハリケーン:ええ、私はそれを無視することができました、そして、私はほとんどしました。もし解決策がそれほど簡単でなかったら私はおそらく持っていたでしょう。しかし、ネイティブAPI用のシムを作成しているので、できるだけすべての基盤をカバーする実装にしたいと思っていました。しかし、私はすでにテストルールを数回試していましたが、これはできませんでした。 –

答えて

1

これが最終結果です。それは私の最初の努力よりも少し強固です。

/** 
* Constructs a regular expression to restore tainted RegExp properties 
*/ 
function createRegExpRestore() { 
    var lm = RegExp.lastMatch, 
     ret = { 
      input: RegExp.input 
     }, 
     esc = /[.?*+^$[\]\\(){}|-]/g, 
     reg = [], 
     cap = {}; 

    // Create a snapshot of all the 'captured' properties 
    for (var i = 1; i <= 9; i++) 
     cap['$'+i] = RegExp['$'+i]; 

    // Escape any special characters in the lastMatch string 
    lm = lm.replace(esc, '\\$0'); 

    // Now, iterate over the captured snapshot 
    for (var i = 1; i <= 9; i++) { 
     var m = cap['$'+i]; 

     // If it's empty, add an empty capturing group 
     if (!m) 
      lm = '()' + lm; 

     // Else find the escaped string in lm wrap it to capture it 
     else 
      lm = lm.replace(m.replace(esc, '\\$0'), '($0)'); 

     // Push to `reg` and chop `lm` 
     reg.push(lm.slice(0, lm.indexOf('(') + 1)); 
     lm = lm.slice(lm.indexOf('(') + 1); 
    } 

    // Create the property-reconstructing regular expression 
    ret.exp = RegExp(reg.join('') + lm, RegExp.multiline ? 'm' : ''); 

    return ret; 
} 

それは私がもともと困難であると考えたものを行います。それは適切に彼らが正しい順序で表示され、それが空のものを見つけたときに停止しない確認します、サブ表現をエスケープします。これは彼らの元の値にすべてのプロパティを復元する必要がありますあなたがそうのようにそれを使用する場合、:

var 
    // Create a 'restore point' for RegExp 
    old = createRegExpRestore(), 

    // Run your own regular expression 
    test = someOtherRegEx.test(someValue); 

// Restore the previous values by running the RegExp 
old.exp.test(old.input); 
1

あなたは、テストのためのラッパー関数を作成しようとすることができます。

var fTest = RegExp.test; 
RegExp.test = function() { 
    var bReturn = fTest.apply(RegExp, arguments); 
    delete RegExp.input; 
    delete RegExp.rightContext; 
    return bReturn; 
} 
+0

これは以前の状態を復元するのではなく(オブジェクトからそれらのプロパティを削除するだけです)、ほとんどのプロパティがゲッターであるところではGoogle Chromeでは機能しません。また、それは望ましくない組み込みの 'RegExp.prototype.test'メソッドの動作を変更しています。 –

関連する問題