正規表現におけるエスケープ処理
JavaScript における正規表現ではパターンを記述するときに「.」や「*」など特別な意味を持つ文字があります。このような文字を特別な意味を持つ文字ではなく、一つの文字として扱う場合にはバックスラッシュ(\)を使ったエスケープ処理が必要となります。またそれ以外にも正規表現リテラルを使用する場合のスラッシュや、 RegExp コンストラクタで文字列を使ってパターンを記述する場合に注意が必要な点があります。ここでは正規表現でパターンを記述する場合のエスケープ処理について解説します。
(Last modified: )
特別な意味を持つ文字をエスケープする
正規表現のパターンで使われる文字の中にはドット(.)やプラス(+)などのように特別な意味を持つ文字があります。これらはメタ文字と呼ばれます。例えば次のような正規表現リテラルで見てみます。
let regexp = /a.b/;
文字のまま解釈すると、このパターンは「a」「.」「b」の 3 つの文字が連続している文字列にマッチするように見えます。実際に RegExp オブジェクトの test メソッドを使って文字列が正規表現とマッチするかどうか試してみると次のような結果となります。
次のサンプルをみてください。
let regexp = /a.b/; console.log(regexp.test('oa.bo')); >> true console.log(regexp.test('oaxbo')); >> true
最初に試した 'oa.bo' は文字列の中に a.b という文字列が含まれるのでマッチするのは分かりますが、次に試した 'oaxbo' は文字列の中に a.b という文字列が含まれていないのにマッチしました。
これはパターンの中でドット(.)を記述した場合、このドットは任意の 1 文字とマッチする特別な意味を持つからです。その為、 /a.b/ は 'a.b' だけでなく 'axb' や 'aYb' など「a」で始まり「b」で終わる 3 文字の文字列にマッチします。
このように正規表現ではパターンの中で使用した場合に特別な意味を持つ文字がいくつか存在します。このような文字に対して特別な意味を持つ文字ではなく、単なる文字としてマッチさせたい場合には、文字の前にバックスラッシュ(\)を記述してエスケープを行います。( Windows 環境は場合はバックスラッシュではなく円記号を使います)。
先ほどのパターンであれば /a.b/ ではなく /a\.b/と記述することで「a」「.」「b」の 3 つの文字が連続している文字列だけにマッチするようになります。次のサンプルをみてください。
let regexp = /a\.b/; console.log(regexp.test('oa.bo')); >> true console.log(regexp.test('oaxbo')); >> false
最初に試した 'oa.bo' は文字列の中に a.b という文字列が含まれるのでマッチしましたが、次に試した 'oaxbo' は文字列の中に a.b という文字列が含まれていないのでマッチしなくなりました。このように特別な文字としてではなく一つの文字として扱う場合には、バックスラッシュを使ってエスケープを行ってください。
なおエスケープを行うために使用するバックスラッシュ(\)も特別な意味を持つ文字なので、バックスラッシュ自身を一つの文字としてマッチさせたい場合は同じようにバックスラッシュを使って '\\' と記述してください。
let regexp = /\\/;
正規表現リテラルを使用する場合のスラッシュについて
正規表現オブジェクトを正規表現リテラルを使って作成する場合、正規表現リテラルでは前後をスラッシュ(/)で囲んで記述するため、パターンの中でスラッシュを記述する場合はエスケープ処理が必要となります。
/パターン/
例えば a/b のようなパターンを正規表現リテラルを使って記述する場合、次のようにそのまま記述してしまうとエラーとなります。
let regexp = /a/b/; >> SyntaxError: Invalid regular expression flags
スラッシュの前にバックスラッシュ(\)を記述してエスケープ処理をしてください。
let regexp = /a\/b/;
正規表現オブジェクトを RegExp コンストラクタを使って作成する場合(文字列としてパターンを指定する場合)はスラッシュは特別な意味を持たないためエスケープする必要はありません。
let regexp = new RegExp('a/b');
RegExpオブジェクトのコンストラクタを使用する場合について
正規表現オブジェクトを RegExp コンストラクタを使って作成する場合に、パターンを文字列で指定するときには注意が必要となります。
new RegExp('パターン');
JavaScript の文字列の中でバックスラッシュは文字に対するエスケープを行う文字という特別な意味を持つ文字なので、バックスラッシュ(\)に対してエスケープ処理が必要となります。(詳しくは「特殊な文字の入力(エスケープシーケンス)」を参照されてください)。
※ 少しややこしいのですが、パターンを文字列として作成したあと、その文字列の中で使われているバックスラッシュが文字列として特別な意味を持つものではないことを示すために、バックスラッシュに対して文字列としてのエスケープ処理がを行います。
例えばパターンの中で \d と記述した場合、バックスラッシュ + d という意味ではなく 0 から 9 までの数字とマッチする特殊な文字としての意味を持ちます。 \d のようなパターンを文字列で記述する場合、バックスラッシュは文字列としてのエスケープ文字ではなくパターンにおける特別な文字とし扱って欲しいので、バックスラッシュの前にバックスラッシュを記述して(文字列としての)エスケープ処理をしてください。
let regexp = new RegExp('\\d');
なお正規表現オブジェクトを正規表現リテラルとして作成する場合はバックスラッシュに対する文字列としてのエスケープは必要はありません。
let regexp = /\d/;
-- --
正規表現でパターンを記述する場合のエスケープ処理について解説しました。
( Written by Tatsuo Ikura )
著者 / TATSUO IKURA
これから IT 関連の知識を学ばれる方を対象に、色々な言語でのプログラミング方法や関連する技術、開発環境構築などに関する解説サイトを運営しています。