perlfaq6の回答から、変数内の正規表現にどのように一致させますか? :
一致演算子 (または正規表現で機能するその他のもの) にパターンをハードコーディングする必要はありません。後で使用するためにパターンを変数に入れることができます。
一致演算子は二重引用符のコンテキストであるため、二重引用符で囲まれた文字列と同じように変数を補間できます。この場合、正規表現をユーザー入力として読み取り、$regex に保存します。$regex でパターンを取得したら、その変数を一致演算子で使用します。
chomp( my $regex = <STDIN> );
if( $string =~ m/$regex/ ) { ... }
$regex 内の正規表現の特殊文字は依然として特殊であり、パターンが有効である必要があり、そうでない場合、Perl は文句を言います。たとえば、このパターンでは対になっていない括弧があります。
my $regex = "Unmatched ( paren";
"Two parens to bind them all" =~ m/$regex/;
Perl が正規表現をコンパイルするとき、括弧をメモリ一致の開始として扱います。閉じ括弧が見つからない場合、次のように文句を言います。
Unmatched ( in regex; marked by <-- HERE in m/Unmatched ( <-- HERE paren/ at script line 3.
状況に応じて、いくつかの方法でこれを回避できます。まず、文字列内のどの文字も特別なものにしたくない場合は、文字列を使用する前に quotemeta でエスケープできます。
chomp( my $regex = <STDIN> );
$regex = quotemeta( $regex );
if( $string =~ m/$regex/ ) { ... }
\Q および \E シーケンスを使用して、一致演算子で直接これを行うこともできます。\Q は Perl に特殊文字のエスケープを開始する場所を伝え、 \E は停止する場所を伝えます (詳細については perlop を参照してください)。
chomp( my $regex = <STDIN> );
if( $string =~ m/\Q$regex\E/ ) { ... }
別の方法として、正規表現の引用演算子である qr// を使用することもできます (詳細については perlop を参照してください)。パターンを引用しておそらくコンパイルし、パターンに正規表現フラグを適用できます。
chomp( my $input = <STDIN> );
my $regex = qr/$input/is;
$string =~ m/$regex/ # same as m/$input/is;
全体を eval ブロックでラップして、エラーをトラップすることもできます。
chomp( my $input = <STDIN> );
eval {
if( $string =~ m/\Q$input\E/ ) { ... }
};
warn $@ if $@;
または...
my $regex = eval { qr/$input/is };
if( defined $regex ) {
$string =~ m/$regex/;
}
else {
warn $@;
}