15

これは少し難問です。どうすれば修正できるか考えていますが、(もっと)簡単な方法があるかどうか疑問に思っています。

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

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

RegExp.input
//-> "football"

RegExp.rightContext
//-> "tball"

これらのプロパティに影響を与えずに正規表現を実行したいと思います。それが不可能な場合 (そして私はそうは思わない)、少なくとも後で以前の値に復元したいと思います。

私は知っていますinput/$_書き込み可能ですが、他のほとんどはそうではないようです。これらすべての値を再適用する正規表現を再構築することも 1 つのオプションかもしれませんが、それは非常に難しいと思います。

これが必要な理由は、ネイティブ API の shim を作成し、test262 スイートを使用してテストしているためです。test262 スイートは、RegExp オブジェクトにこれらのプロパティの予期しない値があるかどうかを確認する特定のテストで失敗します。

4

2 に答える 2

1

テスト用のラッパー関数を作成してみることができます:

var fTest = RegExp.test;
RegExp.test = function() {
    var bReturn = fTest.apply(RegExp, arguments);
    delete RegExp.input;
    delete RegExp.rightContext;
    return bReturn;
}
于 2013-07-10T05:24:54.327 に答える
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);
于 2013-05-23T12:19:32.367 に答える