2021年10月25日

エスケープ、特殊文字

すでに見たように、バックスラッシュ \ は、\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つを消費するためです。
チュートリアルマップ

コメント

コメントする前にこれを読んでください…
  • 改善するための提案がある場合は、コメントする代わりにGitHub issue を送信するか、プルリクエストを送信してください。
  • 記事の内容が理解できない場合は、詳しく説明してください。
  • コードを数語挿入するには、<code> タグを使用し、複数行の場合は <pre> タグで囲み、10行以上の場合 はサンドボックス(plnkr, jsbin, codepen…)を使用してください。