はじめに
案件でJavaScriptを用いた開発中に、正規表現内の特殊文字(メタ文字)のエスケープに関する件で一悶着あったので、個人的なメモの意味も込めて注意すべき点をまとめました。
JavaScriptにおける正規表現
JavaScriptの正規表現は二通りの実装方法があります。
1つがスラッシュで囲んだ正規表現リテラル、そしてもう1つがRegExpコンストラクタを利用する方法があります。
正規表現リテラルでのエスケープ
正規表現リテラルでは、特殊文字を文字として扱う場合にエスケープする必要があります。
そこで注意すべき点として、正規表現リテラルの場合はスラッシュで囲む方式となっているため、スラッシュも特殊文字扱い となります。
そのため、スラッシュを文字として利用する場合は、エスケープする必要があります。
// /a* の文字列をパターンとして用意する場合
const RE = /\/a\*/;
RegExpコンストラクタでのエスケープ
RegExpコンストラクタでは正規表現リテラルと同様に、特殊文字を文字として扱う場合にエスケープする必要があります。
そこで注意すべき点として、RegExpコンストラクタに渡す文字列リテラル内ではバックスラッシュが特殊文字扱いとなっており、 特殊文字をエスケープするためのバックスラッシュをさらにエスケープする必要があるため、バックスラッシュを2つ付ける 必要があります。
※ 正規表現リテラルでは特殊文字扱いだったスラッシュは、文字列リテラルでは特殊文字扱いではないため、文字として利用する場合にエスケープする必要はありません。
// /a* の文字列をパターンとして用意する場合
const RE = new RegExp("/a\\*");
文字クラス内でのエスケープ
例外として、文字クラス1内では特殊文字の扱いが変わるため、以下を文字として扱う場合のみエスケープが必要になります。
対象文字 | 備考 |
---|---|
] |
文字クラスの閉じカッコとして利用されるため |
- |
a-z などのように文字範囲指定に利用されるため |
^ |
文字クラスの先頭に置くことで否定を意味するため。そのため、先頭に文字として置く場合のみエスケープ対象 |
\ |
特殊文字のエスケープに利用されるため |
※ 文字クラス内で上記以外の特殊文字を文字として扱う場合はエスケープが不要となります。
// a] の文字列を文字クラス内のパターンとして用意する場合
const RE1 = /[a\]]/;
// #-& の文字列を文字クラス内のパターンとして用意する場合
const RE2 = /[#\-&]/;
// ^" の文字列を文字クラス内のパターンとして用意する場合
const RE3_1 = /[\^"]/;
// "^ の文字列を文字クラス内のパターンとして用意する場合
const RE3_2 = /["^]/;
// |\ の文字列を文字クラス内のパターンとして用意する場合
const RE4 = /[|\\]/;
-
正規表現では
[]
で囲むとその中で指定したセットの任意の1文字と一致するパターンを作ることができ、それを文字クラスと呼びます。 ↩