sironekotoroの日記

Perl で楽をしたい

Perl入学式 2017 東京 #4 と正規表現キャプチャ変数

  • 教える事で学ぶことがある、とよく言われますがこれは本当にそうで
my $words_ref = [
    'alice loves meat!',
    'bob loves sushi!',
];

このような配列のリファレンスを受け取り, リファレンスに格納された文字列について,「loves」の後に記述されている好きな食べ物の単語を正規表現で取得し,「alice -> meat」, 「bob -> sushi」のように表示するサブルーチン, love_foodを書いてみよう. https://github.com/perl-entrance-org/workshop-2017/blob/master/4th/slide.md

  • うちの解答例がこれ
use 5.012;
use warnings;

my $words_ref = [ 'alice loves meat!', 
                  'bob loves sushi!', ];

for my $line (@$words_ref) {
    if ( $line =~ /(\w+) loves (\w+)/ ) {
         say $1 , "->", $2;
    }
}
  • ここで、受講生の方から以下のようなコード書いたけど、この動作は仕様か?という質問があり
use 5.012;
use warnings;

my $words_ref = [ 'alice loves meat!',
                  'bob loves sushi!',
                  '    loves ramen' ];

for my $line (@$words_ref) {
    if ( $line =~ /(\w+) loves (\w+)/ ) {
         say $1 , "->", $2;
    }else{
        say "\$1 is " , $1; # $1 is bob
        say "\$2 is " , $2; # $2 is sushi
    }
}

  • 正規表現のキャプチャを連続して行なっている時、正規表現のキャプチャにマッチしなかった場合、キャプチャ変数 $1 , $2 の内容は、前回マッチの内容が残る?というもの

  • これ、知らなかったんですが、実際にそうらしく

キャプチャ変数が更新されるのは、マッチが成功した時だけである。マッチが失敗したら、たとえマッチの一部が成功したように見えても、キャプチャ変数の内容はそのまま残る。
Effective Perl 第2版 - Joseph N. Hall, JoshuaA.McAdams, briandfoy - Google ブックス

  • Effective Perl 第2版、持ってるんだけど全くわからなかった・・・