正規表現で使用する文字をエスケープする
はじめに
正規表現でユーザ入力を処理する場合、エスケープ処理が必要になってきます。正規表現を使用した文字列のエスケープについて考えます。
MDNのサンプルコード
JavaScriptのサンプルコードと言えば、おなじみのMDNです。調べてみると、正規表現のページの中にこっそりとサンプルコードが置かれていました。次のコードがそれになります。
// see https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Regular_Expressions#escaping
function escapeRegExp(string) {
return string.replace(/[.*+?^=!:${}()|[\]\/\\]/g, '\\$&'); // $&はマッチした部分文字列全体を意味します
}
※上記のコードでは、「-
」がエスケープされません(漏れているように感じます)
new RegExp("["+escapeRegExp("a+b-c")+"]", "g").test("-") // false
翻訳前の原文も同様の処理でした
自作する
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
- [0-9]: \x30-\x39
function escapeRegExp(string) {
return string.replace(/([\x00-\x2F\x3A-\x40\x5B-\x60\x7B-\x7F])/g, '\\$&')
}
前提条件
- エスケープシーケンスは、数字と大小アルファベットのみ
- 特殊な文字は、ASCII領域内にしかない
- 特殊な文字は、機能拡張によって増加することがある