web-dev-qa-db-ja.com

Perlで正規表現をプリコンパイルする方法はありますか?

Perlで正規表現をプリコンパイルする方法はありますか?プログラムで何度も使用しているものがありますが、使用しても変わりません。

28
Sam Lee

リテラル(静的)正規表現の場合、何もする必要はありません。Perlはそれらを1回だけコンパイルします。

if ($var =~ /foo|bar/) {
    # ...
}

変数に格納されている正規表現には、いくつかのオプションがあります。 qr//演算子を使用して、正規表現オブジェクトを作成できます。

my $re = qr/foo|bar/;

if ($var =~ $re) {
    # ...
}

これは、複数の場所で正規表現を使用したり、サブルーチンに渡したりする場合に便利です。

正規表現パターンが文字列内にある場合は、/oオプションを使用して、Perlが決して変更されないことを約束できます。

my $pattern = 'foo|bar';

if ($var =~ /$pattern/o) {
    # ...
}

ただし、通常はそうしない方がよいでしょう。 Perlは、変数が変更されておらず、正規表現を再コンパイルする必要がないことを知っているほど賢いです。 /oの指定は、おそらく時期尚早のマイクロ最適化です。それは潜在的な落とし穴でもあります。変数has/oを使用して変更した場合、Perlはとにかく古い正規表現を使用します。これにより、バグの診断が困難になる可能性があります。

67
Michael Carman

単純:qr //演算子を確認します( 正規表現の引用のような演算子 の下の perlop に記載されています)。

my $regex = qr/foo\d/;
$string =~ $regex;
19
tsee

明確にするために、プリコンパイルされた正規表現を次のように使用できます。

my $re = qr/foo|bar/;  #precompile phase
if ( $string =~ $re ) ...   #for direct use
if ( $string =~ /$re/ ) .... #the same as above but a bit complicated
if ( $string =~ m/something $re other/x ) ...  #for use precompiled as a part of bigger regex
if ( $string =~ s/$re/replacement/ ) ...  #for direct use as replace
if ( $string =~ s/some $re other/replacement/x ) ... #for use precompiled as a part of bigger, and as replace all at once

これはperlreで文書化されていますが、直接的な例はありません。

0
Znik