正規表現(7) m// の返り値(キャプチャあり)

ここまでは、「キャプチャしない場合」のお話でした。つまり、正規表現キャプチャの為の () カッコが含まれていない場合です。キャプチャが含まれていると、返り値としてキャプチャした文字列がリストになって返ってくるそうです。
どういう事か、スクリプトを書いて確かめてみます。

use strict;
 
my $text = "I like APPLE and BANANA.";
 
my @fruits = $text =~ m/(\w+) and (\w+)/;
 
print "First:  $fruits[0]\n";
print "Second: $fruits[1]\n";

「$text =~ m/(\w+) and (\w+)/」の結果を配列変数 @fruits に代入しています。リストコンテキストですね。(^_^)
「\w」は英単語に使われる文字1つを表しています。

[a-zA-Z0-9_]

と等価で、aからz、AからZの英文字、0から9の数字、「_」アンダーバーのどれかになります。つまり「\w+」は「英単語」にマッチする事になります。
$text の中の「(英単語) and (英単語)」といえば「APPLE and BANANA」ですから、キャプチャされるのは「APPLE」と「BANANA」という事になるはずです。
それを踏まえた上で、実行結果。

First:  APPLE
Second: BANANA

@fruits には「APPLE」と「BANANA」が入った事になります。つまり、m// の返り値がキャプチャされた文字列のリスト、という事ですよね。これはすごい便利。

もう1つ別の例を考えてみます。

my $date = "2006/05/26 15:00";

のような日時を表す文字列があったとします。この文字列から、年月日時分をそれぞれ取得するには以下のような正規表現になります。

m|(\d+)/(\d+)/(\d+) (\d+):(\d+)|;

正規表現の中で「/」(スラッシュ)を使いたかったので、正規表現の区切り文字を「|」にしています。先頭に m を付ければ区切り文字が変えられるんでしたね。
「\d」は数字1文字にマッチします。[0-9]と等価です。
キャプチャした結果がリストで返ってくる事を利用すると、以下のように年月日時分を別々のスカラ変数に入れられます。

use strict;
 
my $date = "2006/05/26 15:00";
 
my ($ye, $mo, $da, $ho, $mi) = $date =~ m|(\d+)/(\d+)/(\d+) (\d+):(\d+)|;
 
print "$ye年$mo月$da日 $ho時$mi分\n";

最初のキャプチャ文字列($1)が $ye に、2番目($2)が $mo に……と、リストに一括代入できます。
実行結果は以下の通り。

2006年05月26日 15時00分

この「リストをリストへ代入」については、長くなりそうなので別のエントリでまとめます。
リスト代入と左辺値