まだ夏の暑さが残る中,僕は少しの間,1人で旅行に出掛けた。特に理由はないが,たまに遠くに出掛けたくなる。もちろん旅先で何をするわけでもない。家で時間をつぶしていたとしても大差はない。ただ見る景色が違うだけだ。まるで写真を撮れる携帯電話か,通話機能付きデジタルカメラかぐらいの差でしかない。しかも旅行中に,大学以来の友人Kからいつものツール作成の依頼があったので,なおさら旅行気分ではなくなってしまった。
Kからの依頼は,「前回作成したツールに新たな機能を追加してほしい」だ。やれやれ,これが旅先の海風に吹かれながら受け取るメールなのだろうか。
今回は,文字列処理において非常に強力な機能である「正規表現」について語ろう。正規表現を用いて,友人Kから依頼されたツールを作成する。
ただし,正規表現はキチンと説明すると,それだけで本が1冊書けてしまう。ここでは,基本的な事柄だけを扱うつもりだ。まずは正規表現の概要を話したあとに,Rubyでの正規表現の使い方を説明しよう。
正規表現=文字列を表現する機能
正規表現は,Ruby独自の機能ではない。元は計算理論という学問で論じられていたもので,文字列を表現する機能だ。いきなり「文字列を表現する機能」と記述しても,意味がわからないだろう。もちろん,あとで説明するので,ちょっとだけ待ってほしい。
正規表現は学術分野で生まれ,徐々にテキスト・エディタやUNIX系のコマンドで採用された。そして,プログラミング言語Perlで大々的に取り入れられたことにより,広く知られるようになった。一時期は「Perlといえば正規表現」と言われたくらいだ。
Rubyは,Perlなどのプログラミング言語を参考に作られた。もちろん強力な正規表現が使用できる。ただし,歴史的に徐々に広がっていったため,一口に正規表現といってもUNIX系コマンドで使用できるものと,Rubyで使用できるものには多少の違いがある。今回は,Rubyで使用可能な正規表現を説明する。
先ほど,正規表現は文字列を表現する機能と説明した。この機能は主に,文字列の検索や置換などに使用する。例えば,ファイルの中に「King Crimson」という文字列があるかどうかを調べるとしよう。「King Crimson」という文字列を検索するだけなら簡単だが,もしかしたらファイル内には,「king crimson」や「KING CRIMSON」というように,大文字や小文字が微妙に違った類似の文字列が混じっているかもしれない。
あるいは「King Crimson」というように,KingとCrimsonの間により多くの空白があるかもしれないし,空白が半角空白ではなくタブであるかもしれない。これらをいちいち自分で調べるのは,真夏の車道を歩くようにうんざりする作業だろう。
こんなときに正規表現が威力を発揮する。正規表現は,表記ゆれをまとめて表現できるからだ。正規表現を使えば,以下のように記述できる。
/King\s+Crimson/i
まだ表現内容はよくわからないだろうが,検索したい「King Crimson」という文字列に「\s+」が組み合わさっているのが見てとれる。また,「/(スラッシュ)」や「i」という文字もある。これらが正規表現を強力にしている演算子だ。詳しくはのちほど説明しよう。とにかく,正規表現を使えば,こんなふうにいくつもの文字列をまとめて表現できるわけだ。