正規表現でエスケープが必要になる文字についてです。
正規表現では、特別な機能をもった文字群を「特殊文字(メタ文字)」と呼ばれます。これらは、見た目には普通の文字と同じものがほとんどです。ですので、機能を持った特別な記号としてではなく、そのまま普通の文字として認識させたいとき、「\(バックスラッシュ)」を用いてエスケープ(迂回)を行います。
今回、エスケープが必要となる特殊文字をまとめました。
目次
正規表現でエスケープが必要な文字
正規表現では、特殊文字を文字として認識させたい時、バックスラッシュを使ってエスケープ(迂回)を行います。どのような文字がエスケープが必要か、つい記憶が曖昧になることが多々ありますので、下記にまとめていきます。
1メタ文字はもれなくエスケープが必要
正規表現中で「メタ文字」などと呼ばれる特殊文字は、もれなくエスケープが必要です。下記はメタ文字の一覧です。
表現 | 意味 |
---|---|
. | 改行(\n、\r)を除くすべての文字 |
^ | 行頭の位置(シングルラインモード:行頭、マルチライン:文章の頭) |
$ | 行末の位置 |
| | 「|」の左右の文字列のいずれか |
\ | 直後のメタ文字をエスケープする |
[、または、] | 文字クラスの開始、終了を表す。 |
(、または、) | サブパターンの開始、終了を表す。 |
{、または、} | 量指定子の開始、終了を表す。 |
このようなメタ文字は、正規表現パターンの中に置かれると、その文字自身ではなく優先的に特別な意味をもつ記号として扱われます。必要に応じて、バックスラッシュでエスケープしましょう。
2デリミタと同じ文字はエスケープが必要
正規表現パターン記述の中で、デリミタとの混同を避けるため、デリミタに利用した文字と同じ文字が出現するのであれば、それらはエスケープする必要があります。
Vimや、PHP(PCRE正規表現)などの多くのプログラミング言語においては、正規表現パターンは、そのパターンの開始と終了を同一の任意の文字で囲むことになっています。これらの囲み文字を「デリミタ(delimiter)」と呼ばれます。
デリミタにはどんな文字を使っても構いませんが、一般的に「/」がよく用いられます。(例えば、javascriptでは、リテラルによる宣言(例:var ptn = /pattern/)によるデリミタは、「/」のみ認めらています。)
//「/」がデリミタなので、パターン中ではエスケープする
$ptn = '/https:\/\/www-creators.com\/archives\/3102/';
但し、上記の例のように元々スラッシュが多く現れる「URL文字列」や「ディレクトリパス」が、パターンに含まれる場合、正規表現を記述しにくくなってしまいます。そのような場合、「#」「~」「@」など別の文字を代わりにデリミタとする事で、エスケープが不要になります。このような工夫によって、正規表現パターンをより簡潔に記述することができるでしょう。
// デリミタを「#」とすることで、スラッシュはエスケープが不要。
$ptn = '#https://www-creators.com/archives/3102#';
文字列表現中のバックスラッシュ
PHPにおいて、クオーテーションを利用した文字列表現においては、「\(バックスラッシュ)」が、「直後の文字を通常文字として扱う」と行った文字エスケープの意味を持っています。
このPHP文字列表現におけるエスケープ機能は、正規表現としてのエスケープ機能を無効化していしまいますので、注意が必要です。これを迂回するため、エスケープにエスケープを重ねる必要があります。見た目が非常の紛らわしいので注意して下さい。
//「\」をマッチする正規表現パターン
$ptn = '#\\\\#';
PHPドキュメントもあわせてどうぞ:
3文字クラス内の特殊文字はエスケープが必要
上記のメタ文字一覧にもありますが、「[」、「]」で文字を囲むと、文字クラスと呼ばれた特別な表現になります。
// a、bかcのいずれかの一文字
[a-c]
このような文字クラスにおいては、前述のような正規表現の通常のメタ文字は特別な意味をもちませんのでエスケープが不要になります。
一方で、文字クラス内でのみ特殊な意味をもつ「-」や「]」はエスケープが必要です。「[」はエスケープは不要ですが、エスケープしても構いません。
下記は紛らわしい例の1つです(このようなパターンが必要になる事が、本当にあるかどうかは疑問です)
// 「-」、「[」、「]」のいずれかの文字
[\[\-\]]
また「文字クラスの否定」を表す「^」は文字クラス開始の「[」の直後でのみ意味を持ちますので、文字クラスの開始が、文字としての「^」であれば、エスケープが必要です。ただし、単純に「^」を開始に配置するのを避けたほうがシンプルでしょう。
// ^、#、$、% のいずれか
[\^#$%]
// 同値
[#$%^]
正規表現のエスケープに関する参考情報
メタ文字やエスケープシーケンスについては、こちらの記事もご覧ください
上記で、「文字クラスの否定」に言及しましたが、興味があれば、こちらの人気記事もご覧ください。
PHP公式ドキュメントでは、PHPでの正規表現にデフォルトに採用されているPCREについて、網羅的な解説があります。PCREとは、Perl 5と同じ文法構文を使った正規表現処理の関数ライブラリです。PCREについて、詳しい情報はこちらが参考になるでしょう。