简体   繁体   English

Perl:在替换字符串变量中使用反向引用

[英]Perl: Use backreferences in a replacement string variable

I am performing a string substitution in Perl, but I have both the pattern and the replacement strings stored as scalar variables outside the regular expression operators.我正在 Perl 中执行字符串替换,但我将模式和替换字符串都存储为正则表达式运算符之外的标量变量。 The problem is that I want the replacement string to be able to use backreferences.问题是我希望替换字符串能够使用反向引用。

I hope the code below will illustrate the matter more clearly.我希望下面的代码能更清楚地说明这个问题。

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";
s/$pattern/My pet $1 is a good boy./

is short for简称

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

The replacement expression ( "My pet $1 is a good boy." ) is a string literal that interpolates $1 .替换表达式( "My pet $1 is a good boy." )是一个插入$1的字符串文字。


This means that这意味着

s/$pattern/$replacement/

is short for简称

s/$pattern/ "$replacement" /e

The replacement expression ( "$replacement" ) is a string literal that interpolates $replacement (not $1 ).替换表达式 ( "$replacement" ) 是插入$replacement (不是$1 ) 的字符串文字。


While it may be hindering you, it's a good thing that perl isn't in the habit of executing the contents of variables as Perl code.虽然它可能会妨碍您,但perl将变量的内容作为 Perl 代码执行,这是一件好事。 :) :)

You can use gsub_copy from String::Substitution to solve your problem.您可以使用String::Substitution中的gsub_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);

That $1 in the replacement string is just successive chars $ and 1 , and to make it into a variable for the first capture you'd have to go through bad hoops.替换字符串中的$1只是连续的字符$1 ,并且要使其成为第一次捕获的变量,您必须通过坏圈来 go 。

How about an alternative换个方式怎么样

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";
}

where the sub is really just潜艇真的只是

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

It's a little more but then it's more capable and flexible.它有点多,但它更有能力和灵活。


Or, as it turns out per ikegami's answer, use String::Substitution which wraps up all the involved 'niceties' into a single call 或者,正如 ikegami 的回答所证明的那样,使用String::Substitution将所有涉及的“niceties”包装到一个调用中

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM