15

びっくりしました

/a/ === /a/

falseJavaScriptで評価します。仕様を読む:

プログラム内の2つの正規表現リテラルは、2つのリテラルの内容が同一であっても、互いに===として比較されることのない正規表現オブジェクトに評価されます。

同等性のテストには使用できないため===、JavaScriptで正規表現の同等性をテストするにはどうすればよいですか?

4

5 に答える 5

20

これは、フラグの順序付けもカバーするケースです。

function regexEqual(x, y) {
    return (x instanceof RegExp) && (y instanceof RegExp) && 
           (x.source === y.source) && (x.global === y.global) && 
           (x.ignoreCase === y.ignoreCase) && (x.multiline === y.multiline);
}

テスト:

regexEqual(/a/, /a/) // true
regexEqual(/a/gi, /a/ig) // also true.
regeXEqual(/a/, /b/) // false
于 2012-05-27T19:28:37.227 に答える
7

関連するすべての正規表現プロパティを完全にテストし、それが正しいタイプのオブジェクトであることを確認する関数を次に示します。

function regexSame(r1, r2) {
    if (r1 instanceof RegExp && r2 instanceof RegExp) {
        var props = ["global", "multiline", "ignoreCase", "source", "dotAll", "sticky", "unicode"];
        for (var i = 0; i < props.length; i++) {
            var prop = props[i];
            if (r1[prop] !== r2[prop]) {
                return false;
            }
        }
        return true;
    }
    return false;
}

また、フラグが新しい機能で正規表現オブジェクトに追加されることがあるため(2012年のこの元の回答以降に発生しましたが、上記のコードは2019年に更新されています)、将来のフラグについてもう少し将来性のあるバージョンを次に示します。特定のフラグのセットを探すのではなく、そこにあるフラグを比較するために追加されます。比較する前にフラグをソートして、実際には機能を変更しない正規表現の指定方法のわずかな違いを考慮に入れます。

function regexSame(r1, r2) {
    return r1 instanceof RegExp && 
           r2 instanceof RegExp &&
           r1.source === r2.source &&
           r1.flags.split("").sort().join("") === r2.flags.split("").sort().join("");
}
于 2012-05-27T19:36:34.180 に答える
2

でタイプを確認してtypeofから、toString()両方の正規表現を使用してそれらを比較できます。/a/giただし、やなどの同等のフラグを持つケースは対象外/a/igです。

function regexEquals(a, b)
{
    if (typeof a !== 'object' || typeof b !== 'object') return false;

    return a.toString() === b.toString();
}

残念ながら、からの特定のタイプはtypeofありません。したがって、それらが正規表現(または正規表現のようなもの)であることを本当に確認したい場合は、次のように実行できます。

RegExp.prototype.regexEquals = function (other)
{
    return (typeof other.regexEquals === 'function')
        && (this.toString() === other.toString());
}

それで:

/a/.regexEquals(/a/); // true
/a/.regexEquals(/b/); // false
于 2012-05-27T19:22:32.283 に答える
2

を使用してそれらを比較し、それらもtoString()確認してください。type

var a = /a/,
    b = /a/;

a.toString() === b.toString() && typeof(a) === typeof(b)  //true

var c = /a/,
    d = /b/;

c.toString() === d.toString() && typeof(c) === typeof(d)  //false
于 2012-05-27T19:24:42.883 に答える
0

上記の回答では、大文字と小文字の区別は考慮されていません。したがって、jfriend00の回答に基づいて構築されているため、関数は次のようになります。

function regexEqual(a, b) {
    if (!(a instanceof RegExp) || !(b instanceof RegExp)) {
        return false;
    }
    let sourceA = a.source;
    let sourceB = b.source;
    const flagsA = a.flags.split('').sort().join(',');
    const flagsB = b.flags.split('').sort().join(',');
    if (flagsA.includes('i') && flagsB.includes('i')) {
        sourceA = sourceA.toLowerCase();
        sourceB = sourceB.toLowerCase();
    }
    return sourceA === sourceB && flagsA === flagsB;
}
于 2019-11-21T05:15:19.470 に答える