English 中文(简体)
普通表达式平等测试
原标题:Testing for equality of regular expressions
  • 时间:2012-05-27 19:19:26
  •  标签:
  • javascript

我惊讶地看到

/a/ === /a/

在 JavaScript 中, false 评估到 false 。通过 thespecs :

Two regular expression literals in a program evaluate to regular expression objects that never compare as === to each other even if the two literals contents are identical.

由于 无法用于测试是否平等, 如何在 JavaScript 中测试正则表达式的平等?

最佳回答

在此设定一个函数,该函数可以充分测试所有相关的正则属性,并确保它是对象的正确类型:

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("");
}
问题回答

这里的例子甚至覆盖了国旗的订单。

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

使用 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

您可以用 type of 检查类型, 然后 to String () 两者都进行正则() 和比较。 它不会覆盖具有等效旗帜的案例, 如 /a/gi /a/ig

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

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

不幸的是,在 type of 中,没有更具体的类型,所以,如果您真的想要确保它们正正反(或正反),您可以按照这些思路做一些事情:

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

然后:

/a/.regexEquals(/a/); // true
/a/.regexEquals(/b/); // false

以上答复没有考虑对案件敏感的问题。因此,在