"Regular Expression" #2
Riue ちゃんの正規表現講座 / 其弐
大好評(嘘つけ)の連載第一回「正規表現講座 / 其壱」は読んでいただけましたでしょうか? 読んでないという貴方(貴女)は、押しつけがましいですがぜひ読んで下さい。
準備はよろしいですか? それでは、早速レクチャーその 1 に入りましょう。
普通の文字も正規表現
まず、最初に一番簡単な正規表現をお見せしましょう。
aこれは、「『a』という文字列にマッチする正規表現」という、立派な正規表現です… いや、殴られるかもしれませんが、本当にそうなんです。
こんな例でしたら、他にいくらでも上げることができますね。
「b」も「y」も正規表現です。つまり、
「メタキャラクタ以外の文字は、その文字自身を表現する正規表現である」
ということになります。
メタキャラクタとして使われる文字を表現したい場合…例えば、「^」
を「^」自身として扱いたい場合についての対処方法については、後程紹介します。
ま、これだけではあんまりにも芸がないですから、もうちょっと違う例をお見せしましょう。
\nこれは「『\n』という文字列に合致する」正規表現に見えますが、ちょっと違います。 これは特別な表現方法で、実は「\n」という 2 文字で 1 文字を表現しています。
わざわざ 2 文字を使ってまで表現したい1文字というのはどのようなものでしょうか? それはもちろん、(通常は)画面上に表現することが出来ない「制御文字」の類です。 「\n」は「改行」を表現しています。
.の登場
さっきの章で正規表現の説明はおしまい、とか言うと、ほんとに殴られますね。 確かに正規表現は正規表現なのですが、さっきの章の内容のみを使っているだけでは、普通に検索したり、 テキスト処理をするのと全く変わりません。 というわけで、もう少し真っ当な正規表現の説明をします。
.
「.」は、どのような文字にでもマッチする正規表現です。
これ 1 文字で、他のどんな文字にもマッチします(但し、「改行」は除きます)。
読み難いかもしれませんが、「.」は「ピリオド」です。
例を見ましょう。
a.cは、「abc」でも「adc」でも「a4c」にでも、とにかく「a と c の間に 1 文字入っていれば」どのような文字列にでもマッチする正規表現です。
同じように .23 は、「123」にでも「z23」にでもマッチします。
Windows ..は、「『Windows』という文字列の次に『空白』があって、『任意の 2 文字』がある」という意味の正規表現ですから、 「Windows 95」にも「Windows 98」にも「Windows NT」にも「Windows Me」にも「Windows XP」にもマッチします。 しかし、「Windows 3.1」にはマッチしません。 「Windows」の次に「空白」があって、「3.1」と 3 文字が続いているから、です(この場合、「Windows 3.」まではマッチします)。
「連続」の表現
正規表現を利用する上で欠かせない表現こそ、次に挙げるメタキャラクタです。
*
「*」は、「直前の文字の 0 文字以上の連続」を表現するメタキャラクタです。
…と言ってもこの説明だけではちょっとわかりにくいので、簡単な例を示しましょう。
6*この正規表現は、「6」にも「66」にも「666」にも「66666666666666666」にもマッチします。 また、「0 文字以上の連続」ですから、空文字列にもマッチします。
このように、「*」は、ある文字の連続を表すのに使われるメタキャラクタです。
「任意の文字の 0 文字以上の連続」を表現する場合は、
「任意の文字の連続」を表現する「.」と組み合わせて、
次のように書くのが常套手段になっています。
.*これを使うと、「doraemon」だろうが「nobitakun」だろうが「123456」だろうが… およそ全ての文字列を表現することが出来ます。 勿論、「空文字列」にもマッチします。
ところで、「*」の使用時には気をつけるべき点が2つあります。
まず、「*」は「1 文字以上の連続」を表現するメタキャラクタではない、ということです。
「1 文字以上の連続」を表現するためには、例えば次のように書かなくてはなりません。
66*これは「『6』の 1 文字以上の連続」を意味する正規表現です。 ですから、「6」や「6666」にはマッチしますが、空文字列にはマッチしません。 同様に、
566*これは、「56」や「56666666」にはマッチしますが、「5」にはマッチしません。
また、「*」は「任意の文字の
0 文字以上の連続」ではなくて、「直前の文字の 0 文字以上の連続」を意味します。
MS-DOS のファイル指定などで使う「ワイルド・カード」と混乱させないで下さい。
必ず「* がどの文字の『0 文字以上の連続』を示しているか」を明示しなくてはいけません。
次の例は、よくやってしまう間違いです。「最後が『ed』で終る文字列」にマッチさせるつもりで次のように書いても、
これはどのような文字列にもマッチしません。
「*」が、「どの文字の連続か」ということを示していないからです。
*edもし、「最後が『ed』で終る文字列」にマッチする正規表現を求めるのなら、 次のように書く必要があります。これは「任意の 1 文字が 0 文字以上連続し、『ed』が続く」という意味になります。
.*ed最初のうちはよく冒してしまう間違いですが、
「*」を使う場合は、必ず「*」の直前に一文字を置く。
ということを忘れないで下さい。
メタキャラクタのエスケープ
先に、
「メタキャラクタ以外の文字は、その文字自身を表現する正規表現である」
ということを書きました。 というわけで、メタキャラクタをメタキャラクタとしてではなく、通常の文字として扱う方法について書いてみます。
「*」という文字を表現する際に、
*
は使えません。「*」は「直前の文字の 0 文字以上の連続」を意味するメタキャラクタだからですね。
しかし、どうしても「*」という文字を正規表現で表現したいときがないとは限りません。
そのような場合は、メタキャラクタをエスケープすることが出来ます。 「エスケープする」とは、「メタキャラクタをメタキャラクタでなくしてしまう」程度の意味に考えておいて下さい。
さて、エスケープの方法ですが、これはそんなに難しくありません。
メタキャラクタの直前に「\」(バックスラッシュ、環境によっては円記号になります)を置くことで、メタキャラクタをエスケープすることが出来ます。
例えば、「78*457」という文字列にマッチする正規表現は
78\*457
になります。「*」の直前にバックスラッシュがない場合は「78*457」という正規表現になり、
当然のように「7457」、「78457」、「788457」、「788888457」…などにマッチしてしまいますが、
バックスラッシュのために「*」がエスケープされますので、「*」が「*」という文字を表現出来るようになります。
とりあえずのおしまい
さて、今回は正規表現を扱う上での基本中の基本についてお話しました。 このページで説明した事項だけで行えることはそんなに多くはありませんが、 これ以降で説明していく「技」と組み合わせていくと、驚くほど強力な力を発揮します。
というわけで、次回に乞う御期待。