びっくりしました
/a/ === /a/
false
JavaScriptで評価します。仕様を読む:
プログラム内の2つの正規表現リテラルは、2つのリテラルの内容が同一であっても、互いに===として比較されることのない正規表現オブジェクトに評価されます。
同等性のテストには使用できないため===
、JavaScriptで正規表現の同等性をテストするにはどうすればよいですか?
びっくりしました
/a/ === /a/
false
JavaScriptで評価します。仕様を読む:
プログラム内の2つの正規表現リテラルは、2つのリテラルの内容が同一であっても、互いに===として比較されることのない正規表現オブジェクトに評価されます。
同等性のテストには使用できないため===
、JavaScriptで正規表現の同等性をテストするにはどうすればよいですか?
これは、フラグの順序付けもカバーするケースです。
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
関連するすべての正規表現プロパティを完全にテストし、それが正しいタイプのオブジェクトであることを確認する関数を次に示します。
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("");
}
でタイプを確認して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
を使用してそれらを比較し、それらも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
上記の回答では、大文字と小文字の区別は考慮されていません。したがって、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;
}