エスケープシーケンス
特殊文字を表現するための文字列。バックスラッシュに続く文字で改行やタブなどを表す。
エスケープシーケンスとは、通常の文字では表現できない特殊文字や制御文字を、バックスラッシュ (\) などのエスケープ文字に続く文字の組み合わせで表現する仕組みです。プログラミング言語、データ形式、ターミナルなど、テキストを扱うあらゆる場面で使われる基本的な概念です。
代表的なエスケープシーケンスには \n (改行)、\t (タブ)、\\ (バックスラッシュ)、\" (ダブルクォート)、\0 (ヌル文字) などがあります。Unicode エスケープとして \u0041 (文字 A) や \u{1F600} (絵文字 😀) のように、コードポイントを直接指定する記法もあります。C 言語系の言語では 8 進数エスケープ (\101) や 16 進数エスケープ (\x41) も使用でき、いずれも A を表します。ただし \u0041 のような 4 桁形式で書けるのは U+FFFF までです。それを超える文字は、ES2015 以降の JavaScript や Rust で使える \u{1F600} のような波括弧形式か、サロゲートペアを並べた \uD83D\uDE00 の形で表現する必要があり (どちらも 😀 と等価)、波括弧形式を持たない Java などでは後者しか選べません。
エスケープの仕組みは文脈によって異なります。JSON ではダブルクォートとバックスラッシュのエスケープが必須で、制御文字 (U+0000 - U+001F) もエスケープする必要があります。HTML では < (<)、& (&)、" (") などの文字参照がエスケープの役割を果たし、XSS (クロスサイトスクリプティング) 攻撃を防ぐためにも重要です。URL では %20 (スペース) のようなパーセントエンコーディングが使われます。
正規表現におけるエスケープは特に複雑です。\. はリテラルのドット (メタ文字の無効化)、\d は数字を表すメタシーケンスです。プログラミング言語の文字列リテラル内で正規表現を書く場合、言語のエスケープと正規表現のエスケープが二重に適用されるため、バックスラッシュ 1 つを表現するのに \\\\ と書く必要がある場面もあります。この「ダブルエスケープ」問題は多くの開発者を悩ませるポイントです。
セキュリティの観点では、エスケープ処理の不備は深刻な脆弱性につながります。SQL インジェクションはシングルクォートのエスケープ漏れが典型的な入口となり、XSS は HTML 特殊文字のエスケープ漏れから生じます。ユーザー入力を他のコンテキスト (SQL、HTML、JavaScript、シェルコマンドなど) に埋め込む際には、そのコンテキストに応じた処理が不可欠です。ただし SQL については、自前のエスケープで守り切ろうとする方針自体が推奨されません。文字集合の解釈差やクォート方法の違いで抜け道が残りやすいためで、プレースホルダによるパラメータ化クエリで値とコードを構造的に分離し、テーブル名のようにプレースホルダを使えない箇所だけを許可リストで検証する、というのが判断の基本になります。
文字数カウントの観点では、エスケープシーケンスはソースコード上の文字数と実際に出力される文字数が異なる点に注意が必要です。\n はソースコード上では 2 文字 (\ と n) ですが、実行時には 1 文字 (改行) として扱われます。\u0041 は 6 文字のソースコードですが、出力は 1 文字 (A) です。絵文字ではこの差がさらに開きます。😀 を \u{1F600} と書けばソースは 9 文字、\uD83D\uDE00 と書けば 12 文字ですが、出力はどちらも見た目 1 文字で、JavaScript の length では 2 と数えられます。文字数カウントツールでソースコードを解析する場合、エスケープシーケンスを展開した後の文字数と展開前の文字数のどちらを表示するかは、ユーザーの用途に応じて使い分ける必要があります。