"Regular Expression" #6
Riue ちゃんの正規表現講座 / 其六
前回に引続き、今回も「拡張正規表現」のお話です。 なお、今回より「ed レベルの正規表現」のことを「限定正規表現」と記述することにします。
「ほげほげ」、または「ふーばー」
さて、今回最初に紹介するのは、「『ほげほげ』か『ふーばー』のどちらか」 という概念を表現するメタキャラクタです。 とは言え、これだけでは流石に何のことだか分かりませんね。
|
「|」は「代替」を意味する正規表現です。
これは、「『|』というメタキャラクタの両側にある正規表現のうち、どちらかの正規表現に一致するものと一致する」という形で定義されます。
簡単に言いますと、限定正規表現のときに説明した「[ab]」という感じですね。
「[]」は「『[』と
『]』で括られた文字の中のどれか 1 文字」
という意味でしたが、「|」は
「『|』」の両側にある正規表現のどちらか一つ」…つまり、
「[]」では「文字単位」でしかなかった選択肢が、
「|」では正規表現レベルにまで拡張されている、と考えればよいでしょう。
それでは、例を見ていきましょう。
Intel|HP「Intel」か「HP」のうち、どちらかが含まれている文字列にマッチします。
[0-9]+kg|0\.[0-9]+t
「|」の定義は
「『|』の両側にある正規表現のうちのどちらか」
ですから、選択肢にメタキャラクタが含まれていても大丈夫です。
この例では、「90kg」や「110kg」などと、「0.04t」や「0.8t」などがマッチしますね。
「|」の効果は 2 つの正規表現に留まりません。
ですから、複数使っても大丈夫です。
IBM|Motorola|Apple「IBM」か「Motorola」か「Apple」にマッチします。
さて、何とも便利に見えるこの「|」ですが、実は両側にある文字列は全て選択肢になってしまいます。
ですから、「Bill Gates」と「Willam Gates」を検索しようとして、次のような正規表現を使うと、思わぬ失敗をします。
Willam|Bill Gatesこの正規表現で、
Bill GatesWillam GatesJohn SculleyWillam Yamada
という名簿を検索すると、
Bill GatesWillam GatesWillam Yamada
「Willam Yamada」という関係ない人物まで検索対象になってしまいました。
これは何故かと言いますと、「『|』の両側にある正規表現がマッチングの対象になる」からです。
つまり、「Willam|Bill Gates」という正規表現は、
「『Willam』か、『Bill Gates』にマッチする」と解釈されてしまうのです。
「これではちょっと使えないぞ…」と思われた貴方も大丈夫。 次に紹介する正規表現で、この疑問はバッチリ解決します。
グルーピング
拡張正規表現の最後を飾るのは「グルーピング」の機能です。 時として、人はモノゴトを「グループ」として考えたくなることがあります。 正規表現を使う時も、それはきっと同じことです。
限定正規表現では、正規表現の最小単位は文字でした。 つまり、文字 1 文字とメタキャラクタを組み合わせて正規表現を作っていたんですね。 しかし拡張正規表現を使うと、任意の正規表現を最小単位として扱うことが可能になります。
()
「(」と「)」で括られた正規表現は、一つの塊として扱われます。
さて、こういう形式的な説明を続けていてもなかなかピンとこないと思いますので、例を出してみましょう。
拡張正規表現の「()」を使うと、例えばこんなことが出来ます。
(Macintosh )?(Plus)これは「『Macintosh 』という文字列が1つあるかないか、 それに「Plus」という文字列が続く』という正規表現です。 「Macintosh 」と「Plus」がそれぞれ一塊として扱われますので、「Macintosh Plus」か「Plus」のどちらかにマッチします。
(Click )+(This)「『Click 』という文字列が 1 つ以上連続し、続いて『This』という文字列がある」という意味になります。 「Click 」と「This」は、やはり一塊で扱われています。 ですから、「Click This!」や「Click Click This!」や「Click Click Click This!」 などがマッチの対象になります。
(PowerMacintosh) ([1-9][1-9][0-9]0)
「PowerMacintosh」という文字列に続いて、1 文字の空白文字、2 桁の
1 から 9 までの文字列、0 から 9 までの文字があって、最後に
0 が続く、という文字列になります。
このように、「()」の中に正規表現で使われるメタキャラクタが混じっていても構いません。
さて、「()」にはもう少し便利な技があります。
それは、「正規表現の範囲を限定する」というものです。
先程、予定通りの動作を期待出来なかった「Willam|Bill Gates」という正規表現、
このように改造すれば大丈夫です。
(Willam|Bill) Gatesこれは、「『Willam』か『Bill』という文字列があり、続いて空白文字が 1 文字、それに『Gates』が続く」という意味の正規表現です。 これなら、ちゃんと「Willam Gates」か「Bill Gates」のどちらかが検索される、というわけです。
このような例を、もう一つ出してみましょう。
(LC|Performa) (520|575|630)これは、「LC 520」「Performa 520」「LC 575」「Performa 575」 「LC 630」「Performa 630」にマッチします。つまり、
- 「LC」か「Performa」という単語があって、
- 空白文字を1文字挟んで、
- 「520」か「575」か「630」という単語が続く
という文字列を表現しています。
とりあえずのおしまい…拡張正規表現
拡張正規表現は、実は意外に使う機会が少なかったりします。 と言うのも、普段使う分には限定正規表現の機能でも十分ですので、限定正規表現の範囲でしか使わないということが多いんですね。 また、拡張正規表現を使えるツールがあまり多くないというのも、その理由になっています。
とは言え、前回と今回説明した機能は、実際に使ってみるとなかなか便利なものばかりです。 機会があれば、積極的に使ってみるのも面白いかと思いますよ。
さて、お待たせしました。次回からはいよいよ「Perl の正規表現」の解説に入ります。 実は、限定正規表現や拡張正規表現よりも、今やこちらのほうが使われる機会が多そうですが…。 ま、数も多いことですので、ゆっくりやっていきましょう。
それでは、また次回まで。