正規表現の \b(単語境界)は多くのエンジンで「単語文字(\w)とそれ以外の境目」を意味するが、\w は通常 ASCII の英数字とアンダースコアしか含まない。日本語の文はそもそも単語間にスペースを入れないため、「こんにちは」のような文字列に \b を使っても期待通りに機能しないことが多い。漢字やひらがなを対象にする場合、単語境界ではなく文字クラスや文脈依存の区切り方を使う必要がある——これは英語の正規表現パターンをそのまま流用するときに見落としやすい落とし穴だ。
JavaScript/JSON文字列でのエスケープ
JSの文字列リテラルやJSONでは、特殊文字はバックスラッシュでエスケープされる。引用符には\"、改行には\n、バックスラッシュ自体には\\を使う。さらにJSONではすべての文字列を二重引用符で囲む必要がある——単一引用符も使えるJSとは異なる点だ。
シェルコマンドでのエスケープ
コマンドラインでは、スペース、引用符、ドル記号、アスタリスクなどが特殊文字にあたり、シェルにとって特別な意味を持つ。コマンドの引数にスペースが含まれる場合はエスケープするか、引数全体を引用符で囲む必要がある。そうしないとシェルはそれを2つの別々の引数に分割してしまう。
正規表現でのエスケープ
正規表現では、ピリオドやアスタリスク、括弧などの文字が特別な意味を持つ(任意の文字、量指定子、グループ)。これらをメタ文字ではなくリテラルとして一致させたい場合は、直前にバックスラッシュを置く:\.は「任意の文字」ではなく、文字通りのピリオドに一致する。
なぜコンテキストごとに個別のエスケープが必要なのか
「二重エスケープ」や「エスケープ不足」のミスは、ユーザー入力のテキスト(例えばスペースを含むファイルパス)をコマンドや文字列に挿入する際にコードが壊れる最も一般的な原因の一つだ。正しいエスケープは、テキストの内容ではなく、それがどこに挿入されるかによって決まる。
何に使うのか
- 日本語を含むユーザーテキストを、JSONリクエストに安全に挿入できる形にする。
- コマンドインジェクションのリスクなしに、動的な引数を含むシェルコマンドを組み立てる。
- 正規表現のリテラルパターンとしてテキストを使う前に、特殊文字をエスケープする(
\bのような単語境界が日本語では期待通り働かない点にも注意する)。
入れ子になったコンテキストでの二重エスケープ
テキストが2つのコンテキストを連続して通過する場合——例えば文字列がJSONに埋め込まれ、そのJSONがシェルコマンドの引数として渡される場合——エスケープは正しい順序で適用する必要がある。まず内側のコンテキスト(JSON)、次に外側のコンテキスト(シェル)の順だ。順序を間違えたり、どこかの階層を飛ばしたりすると、「正しくエスケープしたはずの」文字列が実際には壊れる典型的な原因になる。