正規表現の置換でときどき困るのは、元の文字列が変更されてしまうことです。そのため、たとえば文字列を URI escape する際には、以下のように別変数にコピーした上で、正規表現を適用することになります。
my $escaped = $search_str;
$escaped =~ s/([^0-9A-Za-z_.!~*'()-])/'%' . uc(unpack('H2', $1))/eg;
my $url = "http://example.com/search?q=$escaped";
以前、この点がめんどくさいなーとブログに書いたところ、kazeburo さん他に以下のようなテクニックを教えていただきました。
use List::MoreUtils qw(apply);
my $url = 'http://example.com/search?q='
. apply { s/([^0-9A-Za-z_.!~*'()-])/'%' . uc(unpack('H2', $1))/eg } $search_str;
これなら、不要な変数に頭を悩まされずに1ステートメントで書くことができ、意味も明快です。いいですね。
次は id:amachang。