Perl:置換文字列変数で後方参照を使用する

Aug 21 2020

Perlで文字列置換を実行していますが、パターン文字列と置換文字列の両方が正規表現演算子の外部のスカラー変数として格納されています。問題は、置換文字列が後方参照を使用できるようにしたいことです。

以下のコードが問題をより明確に説明することを願っています。

my $pattern = 'I have a pet (\w+).'; my $replacement = 'My pet $1 is a good boy.'; my $original_string = 'I have a pet dog.';

# Not Working
my $new_string = $original_string =~ s/$pattern/$replacement/r;

# Working
#my $new_string = $original_string =~ s/$pattern/My pet $1 is a good boy./r;

# Expected: "My pet dog is a good boy."
# Actual: "My pet $1 is a good boy." print "$new_string\n";

回答

5 ikegami Aug 21 2020 at 12:23
s/$pattern/My pet $1 is a good boy./

の略です

s/$pattern/ "My pet $1 is a good boy." /e

置換式("My pet $1 is a good boy.")は、を補間する文字列リテラルです$1


この意味は

s/$pattern/$replacement/

の略です

s/$pattern/ "$replacement" /e

置換式("$replacement")は、$replacement(ではなく$1)補間する文字列リテラルです。


邪魔になるかもしれperlませんが、変数の内容をPerlコードとして実行する習慣がないのは良いことです。:)

String :: Substitutiongsub_copyから使用して、問題を解決できます。

use String::Subtitution qw( gsub_copy );

my $pattern         = 'I have a pet (\w+)\.';
my $replacement = 'My pet $1 is a good boy.';
my $original_string = 'I have a pet dog.'; my $new_string = gsub_copy($original_string, $pattern, $replacement);
4 zdim Aug 21 2020 at 09:54

$1置換文字列のそれは、連続する文字$1、であり、最初のキャプチャの変数にするには、悪いフープを通過する必要があります。

代替案はどうですか

my string = q(a pet dog);

my $pattern = qr/a pet (\w+)/; my $new = $string =~ s/$pattern/ repl($1) /er; sub repl { my ($capture) = @_;
    return "$capture is a good boy";
}

潜水艦は本当にただです

sub repl { "$_[0] is a good boy" }

それはもう少しですが、それからそれはより有能で柔軟性があります。


または、ikegamiの回答によると、String :: Substitutionを使用して、関連するすべての「素敵なもの」を1つの呼び出しにまとめます。