正規表現で用いるさまざまなメタキャラクタについて紹介します。なお、正規表現が使える他のソフトやプログラミング言語においてもメタキャラクタの意味はほぼ同じですが、Access(VBA)のものとは若干異なる場合もあります。また、そもそも使えないキャラクタがあったりしますので注意が必要です。
メタキャラクタとリテラル
正規表現のパターンを表す文字列(RegExpオブジェクトのPatternプロパティに設定する文字列)に含まれる文字は、大きく2つの種類に区別されます。
一つは特別な機能を持つ文字(メタキャラクタ)で、もう一つは見たままの意味しかない文字(リテラル)です。
たとえばこれまでの例で用いてきた「[0-9]」というパターンをみてみます。これは「0から9までの半角数字」という意味がありますが、このうち「[」と「]」、そして「-」の3つがメタキャラクタです。これらは文字のリストを作成する機能を持った記号であり、それらの文字自体をマッチングの対象とするものではありません。一方で「0」と「9」がリテラルで、これらは見たままの意味しかありません。
Like演算子による検索でもメタキャラクタは使えますが「*」や「?」など数種類しかありません。しかし正規表現ではたくさんのメタキャラクタが用意されており、詳細な条件でマッチングを行うことが可能です。
メタキャラクタ一覧
制御記号に関するものなど、一部カバーしていないものもありますのでご了承ください。
文字のメタキャラクタ
複数種の文字をまとめて1つの文字として表すものです。何十種もの文字をいちいち列挙することなく、一括して表現することができます。
メタキャラクタ | 意味 |
---|---|
. | 任意の文字(1文字) 「.」は「あ」や「e」「3」などにマッチし、「...」は「やまだ」「Net」などにマッチします なお、キャリッジリターン(Chr(13))にマッチするもののラインフィード(Chr(10))にマッチしません |
[abc…z] | (abc…zはリテラル文字列) abc…zに含まれる任意の1文字 「[あいうえお]」は「あ」「い」「う」「え」「お」の5種の文字にマッチします |
[a-z] | (aとzはリテラル文字) aからzまでの範囲に含まれる任意の1文字 「[あ-お]」は「あ」「い」「う」「え」「お」の5種の文字にマッチします |
[^abc…z] | (abc…zはリテラル文字列) abc…zに含まれない1文字 「[^あいうえお]」は「あ」「い」「う」「え」「お」以外の文字にマッチし、[^あ-お]も同様です |
\ | メタキャラクタをリテラルとしてマッチングしたいとき、その文字の直前に置きます。つまりエスケープ用の記号です 「\.」は「.」にマッチし、「\\」は「\」にマッチします |
\w | 単語を構成する文字 具体的には半角英字(a~zとA~Z)、半角数字(0~9)、アンダースコア(_) |
\W | 単語を構成する文字以外の文字 具体的には半角英字(a~zとA~Z)、半角数字(0~9)、アンダースコア(_)以外の文字 |
\d | 半角数字 具体的には0~9の各文字 |
\D | 半角数字以外の数字 具体的には0~9以外の文字 |
文字のメタキャラクタは文字種を指定するために用いるものです。1つ置けば1つの文字に、3つ置けば3つの文字にマッチングしますが、「この文字種(たとえば半角英字)が3文字か4文字続くものをマッチさせる」とか「あとはこの文字種が何文字続いてもよい」といったように文字の出現回数を柔軟に指定することができません。こうしたマッチングを行うためには下記の「繰り返しのメタキャラクタ」(量指定子)と組み合わせる必要があります。
選択のメタキャラクタ
文字列を列挙し、そのうちの任意のものにマッチさせるためのメタキャラクタです
メタキャラクタ | 意味 |
---|---|
abc…|def… | (abc…とdef…はともにリテラル文字列) 「abc…」と「def…」にマッチし、「|」を加えることでマッチングの対象をさらに増やせます 「東京|名古屋|大阪」は「東京」「名古屋」「大阪」の3種の文字列にマッチします |
選択の対象となる文字列が1文字だけであれば「[あ-お]」も「あ|い|う|え|お」も同じようなはたらきをします(「あ」「い」「う」「え」「お」の5種にマッチ)が、「[あ-お]」は文字種を列挙する結果としてそうなるだけで、意味合いとして両者は異なるものです。
2文字以上の文字列については「[]」を使わない「|」を使うしかなく、「[東京|名古屋|大阪]」としてしまうと「東」「京」「名」「古」「屋」「大」「阪」「|」の8種の文字にマッチしてしまいます(「|」がリテラル扱いになります)。
繰り返しのメタキャラクタ
文字の繰り返し回数を指定するもので、量指定子ともいいます。
リテラルと共に用いることもできますが、特に文字のメタキャラクタと共に用いることで、多様な表現が可能となります。
メタキャラクタ | 意味 |
---|---|
{n} | (nは任意の数値)直前で指定した文字のn回の繰り返し 「[a-z]{5}」は「hello」「enter」などにマッチします |
{n,} | (nは任意の数値)直前で指定した文字のn回以上の繰り返し 「[a-z]{5,}」は「hello」「access」「regular」などにマッチします |
{n,m} | (n,mは任意の数値)直前で指定した文字列のn回以上m回以下の繰り返し 「[a-z]{5,6}」は「hello」「access」などにマッチします |
? | 直前で指定した文字を0回または1回 「ちくわぶ?」は「ちくわ」と「ちくわぶ」の2種の文字列にマッチします なお「?」は「{0,1}」に置き換え可能です |
* | 直前で指定した文字を0回以上繰り返す 「ちくわぶ*」は「ちくわ」「ちくわぶ」「ちくわぶぶ」などにマッチします なお「*」は「{0,}」に置き換え可能です |
+ | 直前で指定した文字を1回以上繰り返す 「ちくわぶ+」は「ちくわぶ」「ちくわぶぶ」などにマッチします なお「+」は「{1,}」に置き換え可能です |
一見なんということはありませんが、量指定子がどのような考え方で機能し、文字列全体の中のどこからどこまでがパターンにマッチするのかを正確に把握することは、正規表現を理解するうえで難しい部分の一つです。これはそもそも正規表現が「文字列の中からマッチするものを見つける」という複雑なマッチングを行うことに一因がありますが(Like演算子は、指定したパターンが「文字列全体にマッチするか」というマッチングしかしないのでその点で単純です)、詳しく見ないとわかりにくいところですので改めて述べたいと思います。
また、複数のメタキャラクタを組み合わせた繰り返しの表現も可能です。この意味についても改めて触れたいと思います。
位置のメタキャラクタ
文字そのものではなくその前後・間の位置を指すもので、アンカーとも呼ばれます。
メタキャラクタ | 意味 |
---|---|
^ | 文字列の先頭 ただし行頭にはマッチしません(ソフト・言語によっては行末にマッチするものもあります) |
$ | 文字列の末尾 ただし行末にはマッチしません(ソフト・言語によっては行末にマッチするものもあります) |
\b | 単語の境界 具体的には上記の「\w」に該当する文字、つまり半角英字(a~zとA~Z)、半角数字(0~9)、アンダースコア(_)が1文字以上連なっているとき、その前後にそれぞれ存在します 例えば「ここでShiftを押す」という文字列がある場合、Sの直前とtの直後に存在します(計2か所) |
\B | 単語の境界以外 具体的には上記の「\w」に該当する文字、つまり半角英字(a~zとA~Z)、半角数字(0~9)、アンダースコア(_)以外の文字が1文字以上連なっているとき、その前後にそれぞれ存在します 例えば「ここでShiftを押す」という文字列がある場合、Sの直前とtの直後以外に存在します(先頭・末尾を含め計10か所。単語の合間にも存在する点に注意) キャリッジリターン(Chr(13))やラインフィード(Chr(10))の前後にも存在します |
意味が分かりにくいかと思いますが、文字の前後にある目に見えない空文字のようなものだと思ってください。これらは基本的にn文字の文字列に対してn+1か所存在します。これらはReplaceメソッドにより他の文字列に置き換えることもできます。
このうち「^」は文字列の先頭を、「$」は末尾を表しています。勘違いしやすいところなのですが、「先頭から近いもの」とか「末尾に近いもの」といった検索順序の指示ではなく、先頭・末尾という存在そのものを表しています。よって、例えば「^こんにちは」は文字列の先頭にある「こんにちは」にしかマッチしませんし、「です$」は文字列の末尾にある「です」にしかマッチしません。
\Bについては、キャリッジリターン(Chr(13))やラインフィード(Chr(10))が単語を構成する文字ではないため、これらの前後にも存在するのが注意点です。ややこしくなるので例は省略しますが、別の機会に詳しく見ていきたいと思います。
グループ化のメタキャラクタ
複数の文字を1つの集まりとして扱うためのメタキャラクタです。
メタキャラクタ | 意味 |
---|---|
(abc...) | (abc...はリテラル文字列) 量指定子による繰り返しの対象を指定する 「つゆ(だく)+」は「つゆだく」「つゆだくだく」「つゆだくだくだく」などにマッチします |
(abc...|def...) | (abc...とdef...はリテラル文字列) 選択の範囲を指定する 「東京(大学|競馬場)」は「東京大学」「東京競馬場」にマッチします 「|」を加えることで選択の対象をさらに増やせます |
上記で述べた機能だけでなく、マッチした文字列をさらにその後のマッチングに活用する、といった重要な機能があります(「同じ文字が2文字続く部分を抽出する」といったように、そもそも対象となる文字種を最初から特定できないときなどに有用な機能です)。これも奥が深い機能なので、改めて述べたいと思います。