正規表現で/o

| コメント(0) | トラックバック(0)



ちなみにこれ、皆はまるところなので昨日の続き:



sub match_me
{
my ($regexp, $string) = @_;
return $string =~ /$regexp/o;
}

これは一見速くなりそうだけど、実はNG。/oを使うと、最初に$regexpに渡した値でこの正規表現はコンパイルされてしまうので、次に違う値を$regexpに渡しても前回の正規表現を使用してしまう。以下テスト:



use strict;

sub poop { my($regexp, $string) = @_ ; return $string =~ /$regexp/o };

my $RE1 = "foo";
my $RE2 = "bar";

my $STRING1 = "foo" x 2;
my $STRING2 = "bar" x 2;

if (poop($RE1, $STRING1)) {
print "$RE1 matches $STRING1\n";
}

if (poop($RE2, $STRING1)) {
print "$RE2 matches $STRING1\n";
}

if (poop($RE1, $STRING2)) {
print "$RE1 matches $STRING2\n";
}

if (poop($RE2, $STRING2)) {
print "$RE2 matches $STRING2\n";
}

daisuke@beefcake daisuke$ perl poop.pl
foo matches foofoo
bar matches foofoo


本当は最初のと最後のがあたるはずなのに、最初の二つしかあたらない。これはどういうことかというと、/oが$regexpをコンパイルするのは最初のpoop()呼び出しの時だけだから。だからこうやって動的に正規表現を作成して使用する場合には/oは使っちゃ駄目駄目。


例えばpoop()の中で繰り返し同じ同じ正規表現を使う場合はqr()を使うと吉:



sub poop {
my($regexp, $string) = @_;

my $compiled = qr($regexp);
for (1..10) {
$string =~ /$compiled/;
}
}


Author

Daisuke Maki (a.k.a lestrrat): Perl hacker, Director of Japan Perl Association, YAPC::Asia Tokyo Organizer (2009-2012), Fluent in Japanese, English. Ex-Brazilian (sorta)

#perl #c #ruby #java #mysql #english #japanese #opensource #stf #cooking #scotch #cigar


このエントリーをはてなブックマ
ークに追加

翔泳社よりモダンPerl入門(2010)を出版させていただいております。できれば内容をアップデートしたいので是非皆様・・・現在の在庫処理にお力をお貸しください!><

月別アーカイブ