正規表現で使えるよう文字列をエスケープする
quotemeta
は、EXPR から /[A-Za-z_0-9]/
に一致しない文字の前にバックスラッシュを付けて返します。
これはダブルクォーテーションで囲まれた文字列での \Q
エスケープと内部的に同じ処理です。
EXPR が省略された場合は $_ が適用されます。
print quotemeta("What's New"), "\n"; # What\'s\ New
print "\QWhat's New\E", "\n"; # What\'s\ New
quotameta
はとりわけ正規表現の中に変数を使いたい場合に重宝します。
次のコードは、エスケープしない部分文字列を正規表現に使った場合を示しています。
my $sentence = 'Hello (^_^)';
my $substring = '(^_^)';
$sentence =~ s/${substring}/(^∀^)/;
print $sentence, "\n"; # 置換されない
上記コードは、$substring の部分文字列に正規表現記号が含まれています。
そのため、文字通りには解釈されず、置換が成功しなかったわけです。
これを解決するのが quotemeta
または \Q...\E
です。
my $sentence = 'Hello (^_^)';
my $substring = '(^_^)';
my $quoted_substring = quotemeta($substring);
$sentence =~ s/${quoted_substring}/(^∀^)/;
print $sentence, "\n"; # 期待通り置換される Hello (^∀^)
次のコードも同じです。
my $sentence = 'Hello (^_^)';
my $substring = '(^_^)';
$sentence =~ s/\Q${substring}\E/(^∀^)/;
print $sentence, "\n"; # 期待通り置換される Hello (^∀^)