-->

正規表現で使用する文字をエスケープする

はじめに

正規表現でユーザ入力を処理する場合、エスケープ処理が必要になってきます。正規表現を使用した文字列のエスケープについて考えていきます。

MDNのサンプルコード

JavaScriptのサンプルコードならば、皆さんおなじみのMDNです。調べてみると、正規表現のページの中にこっそりとサンプルコードが置かれていました。次のコードがそれになります。

// see https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Regular_Expressions (最終閲覧日 2020年02月14日)
function escapeRegExp(string) {
  return string.replace(/[.*+?^=!:${}()|[\]\/\\]/g, '\\$&'); // $&はマッチした部分文字列全体を意味します
}

※上記のコードでは、「-」がエスケープされない(漏れているように感じます)
 new RegExp("["+escapeRegExp("a+b-c")+"]", "g").test("-") // false


翻訳前の原文も同様だったため、下記のように編集申請してみました。

// see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions (最終閲覧日 2020年02月14日)
function escapeRegExp(string) {
  return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}

自作する

MDNのコードも怪しめなので、別の考え方で自作してみます。

考え方は、「数字、大文字アルファベット、小文字アルファベット以外のASCII領域の文字をエスケープする」です。具体的には、次の範囲をエスケープします。

  • ASCII領域: \x00-\x7F
  • [0-9]: \x30-\x39
    • エスケープシーケンスの例:\0=NULL文字
  • [A-Z]: \x41-\x5A
    • エスケープシーケンスの例:\D=数字以外
  • [a-z]: \x61-\x7A
    • エスケープシーケンスの例:\d=数字
  • ASCII領域内で上記以外: \x00-\x2F, \x3A-\x40, \x5B-\x60, \x7B-\x7F
function escapeRegExp(string) {
  return string.replace(/([\x00-\x2F\x3A-\x40\x5B-\x60\x7B-\x7F])/g, '\\$&')
}

※前提:エスケープシーケンスは、数字と大小アルファベットのみ
※前提:特殊な文字は、ASCII領域内にしかない
※前提:特殊な文字は、機能拡張によって増加することがある

コメント