これまで見てきたように、バックスラッシュ \
は文字クラスを表すのに使われます。例: \d
。なので、正規表現の中では特別な文字です。
同様に他にも特殊文字があり、正規表現の中で特別な意味を持ちます。それらはよりパワフルな検索をするために使われます。
これがその完全なリストです: [ \ ^ $ . | ? * + ( )
.
覚えようとする必要はありません – それぞれを個別に見ていく際に、自然と覚えていくでしょう。
エスケープ
特殊文字を通常の文字として使用するには、バックスラッシュを付加します。
それは “文字をエスケープする” とも言われます。
例えば、ドット '.'
を探したいとします。正規表現でドットは “改行以外の任意の文字” を意味します。そのため、本当に “ドット” を意味する場合、前にバックスラッシュ \.
を置きましょう。
alert( "Chapter 5.1".match(/\d\.\d/) ); // 5.1 (マッチ!)
alert( "Chapter 511".match(/\d\.\d/) ); // null (ドット) \. を探します)
括弧も特殊文字なので、それらを探したい場合は \(
を使う必要があります。下の例は文字列 "g()"
を探します:
alert( "function g()".match(/g\(\)/) ); // "g()"
バックスラッシュを探している場合は2つにします:
alert( "1\\2".match(/\\/) ); // '\'
スラッシュ
スラッシュ記号 '/'
は特殊文字ではありませんが、JavaScript では正規表現の開始と終了で使われる(/...pattern.../
)ので、これもエスケープが必要です。
スラッシュ '/'
の検索は次のようになります:
alert( "/".match(/\//) ); // '/'
一方、/.../
ではなく new RegExp
構文を利用する場合、エスケープする必要はありません:
alert( "/".match(new RegExp("/")) ); // '/' が見つかります
new RegExp
new RegExp
で正規表現を作成している場合、/
はエスケープする必要はありませんが、エスケープが必要なものもいくつかあります。
例えばこれを見てください:
let reg = new RegExp("\d\.\d");
alert( "Chapter 5.1".match(reg) ); // null
1つ前の類似の例は /\d\.\d/
が機能しましたが、new RegExp("\d\.\d")
は機能しません。なぜでしょう?
理由は、バックスラッシュが文字列によって “消費される” ためです。覚えているかもしれませんが、通常の文字列文字列には \n
などの独自の特殊文字があり、バックスラッシュはそのエスケープのために使用されます。
どのように “\d.\d” が受け取られるか:
alert("\d\.\d"); // d.d
引用符はバックスラッシュを “消費” して解釈します。例えば:
\n
– は改行文字になります\u1234
– はそのようなコードをもつユニコード文字になります- …そして特殊な意味を持たないもの、
\d
や\z
のようなものの場合には、バックスラッシュは単に除去されます。
したがって、new RegExp
の呼び出しは、バックスラッシュのない文字列を取得します。
これを直すには、引用符で \\
を \
にするためにバックスラッシュを二重にする必要があります。:
let regStr = "\\d\\.\\d";
alert(regStr); // \d\.\d (正しい)
let reg = new RegExp(regStr);
alert( "Chapter 5.1".match(reg) ); // 5.1
サマリ
- 特別な文字
[ \ ^ $ . | ? * + ( )
を文字通り検索するためには、バックスラッシュ\
を先頭に追加する必要があります(エスケープします)。 /.../
を利用する場合、\
もエスケープが必要です(new RegExp
では不要です)。- 文字列を
new RegExp
を渡すとき、文字列の引用符もバックスラッシュを消費するので、2つのバックスラッシュ\\
が必要です。