正規表現(6) m// の返り値(キャプチャなし)

反応が頂けてとても楽しかったですが、そろそろ Perl の勉強に戻りたいと思います。(^_^)

"text" =~ m/pattern/; で検索できますが、この文の返り値はマッチすれば真、マッチしなければ偽と書きました。確かにその通りのようなのですが、もう少し詳しく調べてみます。

Perl には「コンテキスト」(文脈)という概念があり、「配列中の要素を数える」や「返り値を返す」などで勉強しました。
スカラ変数に代入する時や、スカラ値と比べられた時などは「スカラコンテキスト」、配列変数に代入する時や、関数に引数を渡す時*1などは「リストコンテキスト」で評価されます。
Perl の関数は「どのコンテキストで評価されたか」によって返り値が変わる場合が多く、この m// 演算子も例外ではありません。

ラクダ本によると、スカラコンテキストで "text" =~ m/pattern/; を使って文字列を検索すると、マッチすれば「1」が、マッチしなければ「""」(空の文字列)が返ってくるそうです。これを if 文の条件部に使うと「マッチしたかどうか」で分岐できるのは、「1」は真として、「""」は偽として評価されるからですね。
確かめてみます。

use strict;
 
my $text = "This is a Perl script!";
 
my $result1 = $text =~ m/Perl/;   # マッチする
my $result2 = $text =~ m/Pearl/;  # マッチしない
 
print "--$result1--\n";
print "--$result2--\n";

$result1、$result2 はともにスカラ変数ですので、「$text =~ m/pattern/;」はスカラコンテキストで評価される事になります。わかりやすいように、結果の前後に「--」を付けて表示してみました。
実行結果です。

--1--
----

確かに、マッチした時は 1 が、マッチしない時は空文字が返ってくるようです。

また、「$result1」を「@result1」に、「$result2」を「@result2」に置き換えて、m// をリストコンテキストで評価してみても、実行結果は全く同じでした。
ラクダ本によると、リストコンテキストの場合、マッチすれば「(1)」(1 という要素1つだけのリスト)が、マッチしなければ「()」(空リスト)が返ってくるそうです。これを print すると「1」「""」と全く同じ表示になるわけですね。

しかし、ここまでは「正規表現の中にキャプチャがない場合」の話です。キャプチャがある場合は返り値が変わってきます。
正規表現(7) m// の返り値(キャプチャあり) へ続く。

*1:関数を宣言する際の「プロトタイプ」にもよるらしいですが、通常はリストコンテキストで評価されます。プロトタイプについては詳しく勉強するつもりです。