この章では、Perlの強力な武器の1つ、正規表現についてお話します。 カウンターや掲示板、チャットなどのCGIを作るのにPerlが適しているのも、この正規表現が充実しているからです。 正規表現は、とても奥が深く、それだけで1冊本が書けてしまうほどです。 ですから、ここではほんの触りだけを紹介します。
さて突然ですがここで質問です。 次の5つの文のうち、「僕は」で始まり、「猫が好き。」で終わるのはどれでしょうか?
僕は、猫が好き。
やっぱり僕は猫が好き。
僕は、猫が好きかも知れない。
僕は犬よりも猫が好き。
僕は猫が好き?
答えは1番目と4番目ですね。 これを正規表現を使って表すと、
/^僕は.*猫が好き。$/
となります。 これがなぜなのかはこれから見ていくとして、正規表現とは、文字列のパターンを記述するための方法です。 Perlは、ユーザからの入力やファイルの中身などのテキストからこのパターンを探し出し、True/Falseを返す、あるいは別の文字列と置きかえるなどの処理を行います。
まずは単純なところから。 文字1個にマッチさせるには、その文字をパターンマッチ演算子/(スラッシュ)で囲みます。 例えば/a/は、
can, katsu, gachoon
等にマッチします。 マッチする文字が複数あるときは、文字列の中の先頭に近い方の文字にマッチします。 例えば、
My name is can.
という文に対しては"name"のaにマッチします。 ただし、次のメタ文字は特別な意味を持っているので、自分自身と同じ文字にはマッチしません。
^ \ [ $ * + ? . { ( ) |
これらの文字にマッチさせるには、その前に\をおいて保護してやります。 例えば"$100"にマッチさせたいのなら、
/\$100/
とします。
参考までに上のメタ文字の意味を一部紹介しておきます。
メタ文字 | 意味 |
---|---|
^ | 行の先頭にマッチ |
\ | メタ文字を文字として認識させる |
[ ] | 文字クラス |
$ | 行末にマッチ |
* | 直前の文字0個以上の繰り返し |
+ | 直前の文字1個以上の繰り返し |
. | 改行文字以外の任意の文字にマッチ |
( ) | グルーピング |
| | 選択 |
またPerlでは、英文字1文字の前に\をつけるとメタ文字として扱われることがあります(「§2.1 スカラー」参照)。 パターンの中の文字列はダブルクォート文字列として扱われますので、これらのメタ文字も使用できます。 次に上のメタ文字の中から、大事な物をいくつか紹介します。
.(ドット)
.(ドット)は、改行文字以外の任意の1文字にマッチします。 例えば/.a/は、"tama"や"taro"等にマッチします。 しかし、"apple"や"ayoiyoi"にはマッチしません。
文字クラス
[ ](ブラケット)で囲んだ文字の集合を文字クラスといいます。 [ ]で囲んだ文字のいずれかにマッチします。 例えば[abcd]は、
apple, banzai, can, dehehe
等にマッチします。 また、文字クラスの中の-(ダッシュ)は範囲を表します。 例えば[a-z]は小文字のaから小文字のzまでのアルファベットのいずれかにマッチします。
[1-9] #[123456789]と同じ
[a-zA-Z0-9_]
#大文字と小文字のアルファベット、数字、
#アンダースコア(_)のいずれかにマッチ
[の次に^(キャレット)があると、その後に続く文字列に含まれていない文字列にマッチします。
[^0-9] #数字以外にマッチ
よく使われる文字クラスには、次のような略記法が用意されています。
略記法 | 文字クラス |
---|---|
\w | [a-zA-Z0-9_] |
\W | [^a-zA-Z0-9_] |
\d | [0-9] |
\D | [^0-9] |
\s | [\r\n\t\f] |
\S | [^\r\n\t\f] |
ここで少し例を紹介します。 次のスクリプトは、いろいろな単語のリストから、指定したパターンにマッチする物だけを選んで表示させる物です。 @wordsの中身や正規表現の部分をいろいろと変えて遊んでみてください。
@words = ("Apple", "anthony", "Becky", "can", "dehehe",
"Evans", "FRED", "Grant", 20010822, 1023, "hanako");
foreach (@words) {
if(/[AbcDE]/){
print "$_, ";
}
}
この節では正規表現のごくごく基本的なことを見てきました。 本当はもっと書きたいのですが、1ページがあまり長くなるのもあれなので、次の節にまわすことにします。