すでに見たように、バックスラッシュ \
は、\d
のような文字クラスを表すために使用されます。したがって、(通常の文字列と同様に) 正規表現における特殊文字です。
[ ] { } ( ) \ ^ $ . | ? * +
のように、正規表現において特別な意味を持つ他の特殊文字もあります。これらはより強力な検索を行うために使用されます。
リストを覚えようとしないでください。すぐにそれらを個別に扱い、自動的に頭に入るでしょう。
エスケープ
たとえば、文字通りドットを見つけたいとします。「任意の文字」ではなく、単にドットです。
特殊文字を通常の文字として使用するには、バックスラッシュを前に付けます: \.
。
これは「文字のエスケープ」とも呼ばれます。
例
alert( "Chapter 5.1".match(/\d\.\d/) ); // 5.1 (match!)
alert( "Chapter 511".match(/\d\.\d/) ); // null (looking for a real dot \.)
括弧も特殊文字なので、括弧が必要な場合は、\(
を使用する必要があります。以下の例は、文字列 "g()"
を探します。
alert( "function g()".match(/g\(\)/) ); // "g()"
バックスラッシュ \
を探す場合、これは通常の文字列と正規表現の両方で特殊文字であるため、二重にする必要があります。
alert( "1\\2".match(/\\/) ); // '\'
スラッシュ
スラッシュ記号 '/'
は特殊文字ではありませんが、JavaScript では正規表現を開閉するために使用されます: /...pattern.../
。そのため、エスケープする必要もあります。
スラッシュ '/'
の検索は次のようになります。
alert( "/".match(/\//) ); // '/'
一方、/.../
を使用せずに、new RegExp
を使用して正規表現を作成する場合、エスケープする必要はありません。
alert( "/".match(new RegExp("/")) ); // finds /
new RegExp
new RegExp
で正規表現を作成している場合、/
をエスケープする必要はありませんが、他のエスケープが必要になります。
たとえば、これを考えてください。
let regexp = new RegExp("\d\.\d");
alert( "Chapter 5.1".match(regexp) ); // null
以前の例の1つでの同様の検索は、/\d\.\d/
で機能しましたが、new RegExp("\d\.\d")
は機能しません。なぜでしょう?
その理由は、バックスラッシュが文字列によって「消費」されるからです。思い出せるように、通常の文字列には \n
のような独自の特殊文字があり、バックスラッシュはエスケープに使用されます。
これが「\d.\d」がどのように認識されるかです。
alert("\d\.\d"); // d.d
文字列クォートはバックスラッシュを「消費」し、独自に解釈します。たとえば
\n
– 改行文字になります。\u1234
– そのコードを持つ Unicode 文字になります。- …そして、
\d
や\z
のように特別な意味がない場合は、バックスラッシュが単に削除されます。
そのため、new RegExp
はバックスラッシュのない文字列を取得します。それが検索が機能しない理由です!
修正するには、バックスラッシュを二重にする必要があります。文字列クォートは \\
を \
に変換するためです。
let regStr = "\\d\\.\\d";
alert(regStr); // \d\.\d (correct now)
let regexp = new RegExp(regStr);
alert( "Chapter 5.1".match(regexp) ); // 5.1
まとめ
- 特殊文字
[ \ ^ $ . | ? * + ( )
を文字通り検索するには、バックスラッシュ\
を前に追加する必要があります(「エスケープ」します)。 /.../
の内部にある場合は/
もエスケープする必要があります(ただし、new RegExp
の内部では必要ありません)。- 文字列を
new RegExp
に渡す場合は、バックスラッシュ\\
を二重にする必要があります。文字列クォートが1つを消費するためです。
コメント
<code>
タグを使用し、複数行の場合は<pre>
タグで囲み、10行以上の場合 はサンドボックス(plnkr, jsbin, codepen…)を使用してください。