我很惊讶地看到了
/a/ === /a/
在JavaScript中评估为false
。阅读the specs:
程序中的两个正则表达式文字计算为常规 表达式对象,即使相互之间也不会相互比较为=== 两个文字的内容完全相同。
由于===
不能用于测试相等性,如何在JavaScript中测试正则表达式的相等性?
答案 0 :(得分:17)
这是一个甚至涵盖标志排序的案例。
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
答案 1 :(得分:4)
这是一个完全测试所有相关正则表达式属性的函数,并确保它是正确的对象类型:
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("");
}
答案 2 :(得分: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
答案 3 :(得分:1)
使用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
答案 4 :(得分:0)
以上答案未考虑区分大小写。因此,该函数应建立在jfriend00's answer上,
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;
}