当我使用之前定义的 $1 和 $2 时,搜索和替换不起作用。
当我将其存储在新变量中时,它可以工作。
无法按预期工作。
perl -e'
my $name = "start middle end";
my $rep = "";
my $orig = "";
if ($name =~ /sta(.*?)sw+s(.*)/) {
$orig = $1;
$rep = $2;
$name =~ s/$1/$2/;
print "$namen";
}
'
sta middle end
是因为 1 美元和 2 美元在新$name中被替换了吗 =~ 我在做?
按预期工作。
perl -e'
my $name = "start middle end";
my $rep = "";
my $orig = "";
if ($name =~ /sta(.*?)sw+s(.*)/) {
$orig = $1;
$rep = $2;
$name =~ s/$orig/${rep}/;
print "$namen";
}
'
staend middle end
有没有更好的班轮来做到这一点?我不想定义新变量。
通过在 s///运算符的第一部分中运行匹配来重置捕获变量,以供替换使用。列表上下文中的 m//运算符将返回捕获的值,以便您可以轻松地在其中分配它们。此外,如果您的搜索字符串不是正则表达式,您可能希望使用 \Q (quotemeta(。
perl -e'
my $name = "start middle end";
if (my ($orig, $rep) = $name =~ /sta(.*?)sw+s(.*)/) {
$name =~ s/Q$orig/$rep/;
print "$namen";
}
'
sta middle end
是的,新的成功正则表达式匹配取代了$1
和$2
。
您可以完全避免全局变量,如下所示:
perl -e'
my $name = "start middle end";
if ( my ($orig, $rep) = $name =~ /sta(.*?)sw+s(.*)/ ) {
$name =~ s/Q$orig/$rep/;
CORE::say $name;
}
'
更好的是,您可以避免进行以下两场比赛:
perl -e'
my $name = "start middle end";
if ( $name =~ s/staK.*?(?=sw+s(.*))/$1/ ) {
CORE::say $name;
}
'
但是,我会使用以下方法:
perl -e'
my $name = "start middle end";
if ( (my ($prefix, $suffix, $foo) = $name =~ /^(.*?sta).*?(sw+s(.*))/ ) {
CORE::say "$prefix$foo$suffix";
}
'
请注意,您的代码遭受了代码注入错误,我使用 quotemeta
修复了该错误(如Q
(。
在这里,以防万一,我们会有意想不到的额外空格,我们也可以尝试这个表达式:
(sta)([a-z]*)s+(w+)s+(.+)
这只是另一种选择。
测试
perl -e'
my $name = "start middle end";
$name =~ s/(sta)([a-z]*)s+(w+)s+(.+)/$1$4 $3 $4/;
print "$namen";
'
输出
staend middle end
请在此处观看演示
替换部分中的$2
是指来自同一替换的图案部分中的捕获组。因此,您只需要一个变量即可记住 $2。
perl -lwe '$_ = "start middle end" ; if (/sta(.*?)sw+s(.*)/) {my $rep = $2; s/$1/$rep/; print}'
staend middle end
您可以通过使用最后一个匹配开始和结束全局数组@-
和@+
并只执行子字符串替换来避免其他变量:
my $name = "start middle end";
if ($name =~ /sta(.*?)sw+s(.*)/) {
substr($name, $-[1], $+[1]-$-[1], $2);
print "$namen";
}
请参阅perldoc perlvar
中@-
条目
正则表达式捕获变量根据代码
表现出奇怪的行为流,函数调用和其他东西。
要完全解释和理解这一点,需要几页
的解释。
至于现在,避免整个混乱,只使用一个正则表达式
perl -e'
my $name = "start middle end";
$name =~ s/^(sta)(.*?)(sw+s)(.*)/$1$4$3$4/;
print "$namen";
'