正規表現(3)〜オプションと置換

とりあえずの更新3つめ。今日上げた他の2つの記事と合わせて、後日書き直します。

$s =~ /.+/ # '/' でなくてもよい。ただし、その場合は'm'を省略することができない。
$s =~ m/.+/
$s =~ m!.+!
$s =~ m%.+%
$s =~ m{.+}

### URL(例) ###
$_ = 'http://www.keyman.or.jp/3w/hoge/fuga.html';
print int(m%^https?://((\w+\.)*\w+/)*(\w+\.)*\w+\z%)."\n";

### 正規表現オプション ###
$s =~ /abc/i; #=> 大文字小文字を無視
print int 'ABC' =~ /abC/i

$s =~ /abc/s; #=> シングルラインモード
print int "aaa\nbbb" =~ /a+.b+/;  #=> fault
print int "aaa\nbbb" =~ /a+.b+/s; #=> ture

$s = 'abcde';
while($s =~ /([ace])/g)
    print "---$1---\n"
}

'abcABCabc' =~ /([A-Z]+)/
print "---$1---\n";

#リストに結果を渡すと、$1, $2...の特殊変数にマッチ結果は入らない。=>リストに結果を渡さない場合、$1, $2...の特殊変数が上書きされていく。
#あとで結果を使いたい時は定義した変数に入れておく。
my($x,$y,$z) = ('abcABCabc' =~ /([a-z]).+([A-Z]).+([a-z])/)
print "---$x/$y/$z---\n"; #=> a/C/c 繰り返しがつくと、最長マッチしようとする。

my($x,$y,$z) = ('abcABCabc' =~ /([a-z]).+?([A-Z]).+?([a-z])/) #最短マッチの+?がある
print "---$x/$y/$z---\n";

my($x,$y,$z) = ('abcABCabc' =~ /([a-z])+([A-Z])+([a-z])/)
print "---$x/$y/$z---\n"; #=>cCa

my($x,$y,$z) = ('abcABCabc' =~ /([a-z]+)([A-Z]+)([a-z]+)/);
print "---$x/$y/$z---\n";

#splitの第一引数で()を使うと、区切り文字も配列に入れる
#()を使うと、$1, $2...も返そうとするため。
my @s = split(/([=&])/, 'aaa=bbb&ccc=ddd');
print join('#', @s)."\n"; #「aaa#bbb#ccc#ddd」にはならないよー。

my @s = ('aaa=bbb&ccc=ddd' =~ /(\w+)/g)
print join('#', @s)."\n";

$id = '10000001T003'
my($pid, $tid) = ($id =~ /^(\d{8})(T\d{3})\z/);


### 文字置換 ###
#変数以外のものに変更を加えることはできないので、変更を加えたい時は変数にしてから処理を行う。
#変数でない物を変更しようとすると、「can't modify constant ... (定数は変更できないよ)」と怒られる。
(my $abc = 'ABC') =~ s/B/b/;
print "---$abc---\n";

(my $abc = 'ABC') =~ s/./b/;
print "---$abc---\n"; #=> bBC

(my $abc = 'ABC') =~ s/./b/g;
print "---$abc---\n"; #=> bbb

(my $abc = 'abcde') =~ s/[bcd]/#/;
print "---$abc---\n";

#s///の場合は、以下のような後方参照の使い方もできる。\1と$1は同じ。
#$1は、b c dの順に値が変わっていく。
#もちろん、$2, $3...と使える。
(my $abc = 'abcde') =~ s/([bcd])/<\1>/g;
print "---$abc---\n";
(my $abc = 'abcde') =~ s/([bcd])/<$1>/g;
print "---$abc---\n";

#src=>"xxx", width=>"100"というハッシュを作るとき
my $tag = q(<img src="xxx" width='100'>);
%ATR;
while($tag =~ / +(\w+)=("(.*?)"|'(.*?)')/g{{
    print "1:$1, 2:$2, 3:$3, 4:$4\n";
    $ATR{$1} = "$3$4";
}

#m//のときは、\1もしくは\1として参照できる。この場合、$1は使えない。必ず、バックスラッシュか\。
my $tag = q(<img src="xxx" width='100'>);
while($tag =~ / +(\w+)=(["'])(.*?)\2/g{{
    print "1:$1, 2:$2, 3:$3\n";
}

#s///の場合は、スカラーに渡そうがリストに渡そうが、置換に成功した回数を返す。
my $abc = 'abcde';
my($x) = ($abc =~ s/([bcd])/<$1>/g); #=> 回数を返す
my $y = ($abc =~ s/([bcd])/<$1>/g);  #=> 回数を返す
print "---$x/$y---\n";

### 問題 ###
my $xxx = '10, 20, 30';
数字を <> で囲ってください

(my $xxx = '10, 20, 30') =~ s/(\d+)/<$1>/g;

my $xxx = '<10>, <20>, <30>';

数字を2倍にしてください
my $xxx = '10, 20, 30';
#オプションeを付けると、置換する部分をperlとして評価する。つけないと、そういう文字列として評価する。演算子や関数を使用するときなどには付けないとダメ。
$xxx =~ s/(\d+)/ '<' . ($1 * 2) . '>' /eg; #eval => 評価する,実行する。<と>は文字列なので、perlのなかでは''もしくは""で囲わないといけないので囲っている。
$xxx =~ s/(\d+)/ '<' . &test($1) . '>' /eg; #eval => 評価する,実行する。サブルーチンを使うことも可能。


$xxx =~ s/[abc]/hoge/ig;

$x = "aaa\nbbb\nccc\n";
$x =~ s/b.+c/\\n/s;
print "---$x---\n";

#置換の時のデリミタの書き方。sは省略できない。
$xxx =~ s%.+%yyy%;
$xxx =~ s!.+!yyy!;
$xxx =~ s/.+/yyy/;
$xxx =~ s(.+)(yyy); #括弧等、組み合わせがある物は、このように組み合わせて使う。
$xxx =~ s{.+}{yyy};

### 正規表現オプションのまとめ ###
i => 大文字小文字を無視
g => 繰り返し(続きから)
s => .でも改行にマッチできるようにする。これがないと、.は改行にはマッチしない。
e => Perl式として評価する