JavaScriptの正規表現における特殊文字のエスケープ
特殊文字をそのままの文字として扱いたい場合があります。 そのためには、バックスラッシュを使用してエスケープする必要があります。 例を見てみましょう。
例
次の例では、正規表現の作者は、検索パターンを文字
'a'、その後にプラス'+'、その後に
文字'x'としたいと考えていました。
しかし、コードの作者は記号'+'をエスケープしていないため、
実際の検索パターンは次のようになります:
文字'a'が1回以上出現し、その後に
文字'x'が続く:
let str = 'a+x ax aax aaax';
let res = str.replace(/a+x/g, '!');
結果、変数には次の文字列が格納されます:
'a+x ! ! !'
例
今度は、作者がプラスをバックスラッシュでエスケープしました。
これで検索パターンは意図した通りになります:
文字'a'、その後にプラス'+'、
その後に文字'x'。
let str = 'a+x ax aax aaax';
let res = str.replace(/a\+x/g, '!');
結果、変数には次の文字列が格納されます:
'! ax aax aaax'
例
この例のパターンは次のとおりです:文字
'a'、その後にドット'.'、その後に
文字'x':
let str = 'a.x abx azx';
let res = str.replace(/a\.x/g, '!');
結果、変数には次の文字列が格納されます:
'! abx azx'
例
次の例では、作者はスラッシュをエスケープするのを忘れ、 エスケープされていないドットは任意の文字を表すため、 すべての部分文字列が正規表現にマッチしてしまいました:
let str = 'a.x abx azx';
let res = str.replace(/a.x/g, '!');
結果、変数には次の文字列が格納されます:
'! ! !'
注意点
ドットをそれ自身として表すためにバックスラッシュを忘れた場合、 それに気づかないことがあることに注意してください:
'a.x'.replace(/a.x/g, '!'); // '!' を返す。これは期待通り
見た目は正しく動作します(ドットは任意の文字を表すため、
通常のドット'.'にもマッチするからです)。
しかし、置換を行う文字列を変更すると、誤りがわかります:
'a.x abx azx'.replace(/a.x/g, '!'); // '! ! !' を返す。期待は '! abx azx'
特殊文字と通常文字のリスト
通常の文字をエスケープしても問題はありません。それ自体を表します。 例外は数字です。数字はエスケープできません。
ある文字が特殊文字かどうか疑問に思うことがよくあります。 疑わしい文字をすべて片っ端からエスケープする人もいます。 しかし、これは悪い習慣です(正規表現がバックスラッシュで散らかってしまう)。
特殊文字は以下の通りです:$ ^ . * + ? \
/ {} [] () |
特殊文字ではないものは以下の通りです:@ : , ' " ;
- _ = < > % # ~ `& !
実践問題
次の文字列が与えられます:
let str = 'a.a aba aea';
文字列'a.a'のみを見つけ、他の文字列は取得しない正規表現を書いてください。
次の文字列が与えられます:
let str = '2+3 223 2223';
文字列'2+3'のみを見つけ、他の文字列は取得しない正規表現を書いてください。
次の文字列が与えられます:
let str = '23 2+3 2++3 2+++3 345 567';
文字列'2+3'、'2++3'、'2+++3'を
見つけ、他の文字列は取得しない正規表現を書いてください(+の数は任意)。
次の文字列が与えられます:
let str = '23 2+3 2++3 2+++3 445 677';
文字列'23'、'2+3'、'2++3'、
'2+++3'を見つけ、他の文字列は取得しない正規表現を書いてください。
次の文字列が与えられます:
let str = '*+ *q+ *qq+ *qqq+ *qqq qqq+';
文字列'*q+'、'*qq+'、'*qqq+'を
見つけ、他の文字列は取得しない正規表現を書いてください。
次の文字列が与えられます:
let str = '[abc] {abc} abc (abc) [abc]';
角括弧内の文字列を見つけ、'!'に置き換える正規表現を書いてください。