sironekotoroの日記

Perl で楽をしたい

Perl言語プログラミングレッスン[入門編] 第8章

結城先生は面白い問題作るよなぁ

  • 以下のスクリプトで$&,$1,$2,$3に該当するのは?
use strict;
use warnings;

my $str = 'The price is 300yen. The distance is 120km.';
if ( $str =~ /((\d+)([A-Za-z]+))/ ) {
    print $&, "\n";
    print $1, "\n";
    print $2, "\n";
    print $3, "\n";
}
  • $1,$2,...は左カッコの順で決まる

    • $&は最初にマッチしたものだから300yen
    • $1は300yen
    • $2は300
    • $3はyen
  • 修飾子xで正規表現にコメントをつける

    • x を入れないとエラーになる。
if ( $str =~ /(       # 1つ目の左カッコ $1
  (              # 2つ目の左カッコ $2
      \d+            # 正規表現 \d+ 数字の繰り返し
      )          # $2の範囲終わり
      (          # 3つ目の左カッコ $3 
      [A-Za-z]+  # 英語の大文字小文字の繰り返し
      )          # $3の範囲終わり
  )              # $1の範囲終わり
/x ) {                # 修飾子x
  • 繰り返しマッチは修飾子g
    • ifではなくてwhileになってるのに注意
my $str = 'The price is 300yen. The distance is 120km.';
while ( $str =~ /((\d+)([A-Za-z]+))/g ) {
    print $&, "\n";
    print $1, "\n";
    print $2, "\n";
    print $3, "\n";
}
  • 正規表現の中で変数を使う
    • こんな技があるなんて
  • 英単語の2文字目と3文字目が同じものをマッチさせたい
use strict;
use warnings;

my $word = "see";

if ( $word =~ /[bcdfghjklmnpqrstvwxyz]([aiueo])\1/ ) {
    print $&, "\n";
}
else {
    print "No match", "\n";
}

$word = "sea";

if ( $word =~ /[bcdfghjklmnpqrstvwxyz]([aiueo])\1/ ) {
    print $&, "\n";
}
else {
    print "No match", "\n";
}
  • //の代わりにm||
    • さらに、m|\Q 〜 \E|と\Q \Eで挟むことでエスケープが不要になって楽
use strict;
use warnings;

my $uri = 'http://www.yahoo.co.jp/news';

if ($uri =~ /http\:\/\/www\.yahoo\.co\.jp/){
    print "Yahoo","\n";
}else{
    print "not yahoo","\n";
}

if ($uri =~ m|\Qhttp://www.yahoo.co.jp\E|){
    print "Yahoo","\n";
}else{
    print "not yahoo","\n";
}
  • 修飾子eでマッチしたものを評価する
    • s///e
    • 正規表現でマッチした文字を単に置き換えるだけではなく、perlの式でさらに加工できるのか
use strict;
use warnings;

my $str = 'How I wonder what you are';

if ($str =~ s/\w+/ucfirst($&)/eg){
    print $str,"\n";
}

my $data = '13 B8 56 0B BC 8F DB B5';
if ($data =~ s/(\w+)/hex($&).','/eg){
print $data,"\n";
};
  • 単語境界 \b
    • 知りませんでした・・・知らないことばっかりだわ
use strict;
use warnings;

my $str = "Loves plum cake and sugar candy.";
print $str,"\n";

$str =~ s/and/AND/g;
print $str,"\n";   # andがANDに、しかしcandyはcANDyに

# 単語境界 \b を導入する

$str = "Loves plum cake and sugar candy.";

$str =~ s/\band\b/AND/g;
print $str,"\n";   # andがANDに、candyはcandyに