速習正規表現
なんとなく正規表現入門講座。知っている人が読んでも何の参考にもならないレベルなので読み飛ばしてください。(^^;
・ワイルドカードとごっちゃにしない
ワイルドカードと正規表現では*や?の意味が違います。
ワイルドカードの場合、
A*
と、あればAの後に任意の文字が続く、もしくは続かなくてもよい。
つまり、Aではじまっていれば、AだけでもABでもABCでも何でも良い訳です。
ところで、このワイルドカードにおける*は実は2つのことを意味しています。
- どんな文字でもよい
- 何文字でもよい
ワイルドカードではこんなこと意識しなくても良いのですが、正規表現の場合は区別しなければなりません。
・量指定子
正規表現では*や?は量指定子と呼ばれ、文字の量(文字数)しか意味しません。量指定子は必ず文字と組み合わせて使い、「指定した文字をどれくらい繰り返すか」ということになります。例えば、
A*
この場合、指定した文字'A'を0文字以上繰り返すという意味となります。ワイルドカードとは意味が全然違いますね。では、ワイルドカードにおけるA*は正規表現でどう指定するかと言いますと、
A.*
と書きます。.(ドット)は任意の一文字を意味し、それが量指定子分繰り返すということになります。
量指定子の種類には
- ?: 0または1
- *: 0以上
- +: 1以上
などがあります。ちなみに+は他の方法で表現できるので必須ではありません。
A+
は
AA*
と書くことが出来ます。
また、ツールによっては範囲指定もサポートしています。
- {min,max}
で、min以上max以下の繰り返しが指定できます。
A{3,5}
この場合、Aが3以上5以下繰り返すものにマッチします。
・量指定子は強欲
ABCZ ABCDZ ABCDEZ ABC
上記のような文字列があったとします。ここからAではじまってZで終わる部分を取得したいとすると、どーすれば良いでしょうか?欲しいのは、ABCZ,ABCDZ,ABCDEZです。
条件をそのまま正規表現のパターンに置き換えると、
A.*Z
こんな感じでしょうか?しかし、これだと意図したとおりにはなりません。どのようになるかと言いますと、まず、
ABCZ ABCDZ ABCDEZ ABC
Aがマッチします。次に.*なので任意の文字がマッチすることになります。
ABCZ ABCDZ ABCDEZ ABC
.*ZなのでZが見つかるまで読み込んだ文字を戻していきます。
ABCZ ABCDZ ABCDEZ ABC
ABCZ ABCDZ ABCDEZ ABC
ABCZ ABCDZ ABCDEZ ABC
となって、マッチとなります。このように量指定子はマッチするだけ全部マッチさせ、このことを強欲とか言ったりします。
・文字クラス
*が強欲なのは分かりましたが、結局のところ期待通りのマッチングさせるにはどうすれば良いのでしょうか?まず、「Aではじまって任意の文字が続いてZで終わる」という表現が曖昧なのが問題です。これは正確には「AではじまってZ以外の文字が続いてZで終わる」というのが正しいです。ここで問題になるのが「Z以外」をどう表すかです。ここまでの知識では無理なので、新しい表現を紹介します。
[ABC]
これも正規表現の1つで、AまたはBまたはCを表します。この'['と']'で括った書き方を文字クラスと呼びます。もちろん、
[ABC]*
このように、量指定子をすることも出来、この場合、AまたはBまたはCが0文字以上続くことを意味します。
さて、文字クラスですが否定表現も可能です。
[^ABC]
このように[^...]と書くと否定の意味となり、この例だとAでもBでもCでもないとなります。これで道具が揃ったので、「AではじまってZ以外の文字が続いてZで終わる」を正規表現で表してみます。
A[^Z]*Z
と指定すれば良いです。
ワイルドカードとの違いと量指定子が強欲であることが押さえられれば、正規表現の勉強がし易くなると思います。
(追記) 一般的には強欲じゃなくて貪欲と呼びますね。と、言うことで修正。と思ったけど、詳細 正規表現みたら両方あった。悔しいから戻す。(^^;