ドット(.)をあらゆる文字にマッチさせる/s:
#!/usr/bin/env perl use v5.12; use warnings; $_ = "I saw Barneyndown at the bowling alleynwith Frednlast night.n"; if (/Barney.*/) { # こっちはマッチしない say "matched"; } if (/Barney.*/s) { # sを付けると、.は改行文字にもマッチするようになる print "That string mentions Fred after Barney!n"; }
正規表現中に空白文字を含める/x:
#!/usr/bin/env perl use v5.12; use warnings; $_ = "I saw Barney down at the bowling alley with Fred last night."; if (m{ Barney .* # 正規表現中のコメントは空白文字とみなされる Fred }x) { print "That string mentions Fred after Barney!n"; }
括弧による文字列のキャプチャと、その制御:
#!/usr/bin/env perl use v5.12; use warnings; my $names = 'Fred or Barney'; # ()で囲った範囲の文字列はキャプチャされ、後方参照や変数での再利用ができる # (?: で始まる括弧では文字列はキャプチャされない if ($names =~ m/(w+) (?:and|or) (w+)/) { say "I saw $1 and $2"; # ()でキャプチャした文字列は$1,$2...で呼び出せる } # Perl5.10以降では、 # (?<ラベル>で始まる括弧でキャプチャした文字列は、 # %+というハッシュに記録され、$+{ラベル}で呼び出せる if ($names =~ m/(?<name1>w+) (?:and|or) (?<name2>w+)/) { say "I saw $+{name1} and $+{name2}"; }
名前付きキャプチャの後方参照:
#!/usr/bin/env perl use v5.12; use warnings; my $names = 'Fred Flinstrone and Wilma Flinstrone'; # 名前付きキャプチャの後方参照には g{ラベル} という記法を使う if ($names =~ m/(?w+) and w+ g{last_name}/) { say "I saw $+{last_name}"; }
自動マッチ変数(括弧でキャプチャしなくても自動でセットされる変数):
#!/usr/bin/env perl use v5.12; use warnings; if ("Hello there, neighbor" =~ /sw+,/) { # 括弧でキャプチャしていない # &`: マッチした部分より前にあるもの # $&: マッチした部分 # &': マッチした部分より後ろにあるもの # 自動マッチ変数3つを連結すると、元の文字列を復元できる say "That was ($`)($&)($')"; }
※自動マッチ変数は、次のマッチが実行されるまで値を保持する
※自動マッチ変数を使うと、プログラム全体の正規表現が少しだけ遅くなる
自動マッチ変数を一部だけ使用する/p(Perl 5.10以上):
#!/usr/bin/env perl use v5.12; use warnings; if ("Hello there, neighbor" =~ /sw+,/p) { # ${^PREMATCH} : マッチした部分より前にあるもの # ${^MATCH} : マッチした部分 # ${^POSTMATCH} : マッチした部分より後にあるもの say "That was (${^PREMATCH})(${^MATCH})(${^POSTMATCH})"; }
感想
Perlの正規表現は機能が豊富で、新しい機能もどんどん追加されている、という話は聞いていたけど、確かにその通りだった。Perlでは、初心者本でここまで詳細に正規表現を解説するのか! と驚いた。
あと、名前付きキャプチャについて、「PHPでも使えないかな」と思って試してみたら、使えた:
<?php if (preg_match('/(?<hoge>hoge)/', 'hogefuga', $matched)) { echo $matched['hoge'], PHP_EOL; // hoge }
教訓:他言語を学ぶことで、メインで使ってる言語についても、より深く学ぶことができる。