鉴于以下代码,
my $string = "foo";
my $regex = s/foo/bar/;
$string =~ $regex;
print $string, "\n";
我原本期望输出为bar
,但它是foo
。为什么会这样,我该如何解决这个问题?
请注意,在我的实际情况中,正则表达式更复杂,我实际上想要将其中的几个存储在哈希中(因此我可以编写类似$string =~ $rules{$key}
的内容)。
答案 0 :(得分:7)
你正在寻找替代品,而不仅仅是正则表达式部分,所以我猜编译的正则表达式(qr//
)不是你想要的,
use strict;
use warnings;
my $string = "foo";
my $regex = sub { $_[0] =~ s/foo/bar/ };
$regex->($string);
print $string, "\n";
您的陈述
my $regex = s/foo/bar/
相当于
my $regex = $_ =~ s/foo/bar/
s///
返回所做的替换次数,或者返回false(特别是空字符串)。所以$regex
现在是''
或1
(如果/g
修饰符生效,可能会更多)
$string =~ $regex
正在执行'foo' =~ //
或'foo' =~ /1/
,具体取决于最初包含的$_
。
答案 1 :(得分:2)
你可以在变量中存储一个正则表达式模式,但是在你的例子中,正则表达式只是foo
,并且还有很多比这个模式更多
语句s/foo/bar/
比看起来更复杂 - 它是一个完全成熟的语句,它将正则表达式模式应用于目标字符串并替换如果找到模式,则为替换字符串。在这种情况下,目标字符串是默认变量$_
,替换字符串是foo
。您可以将其视为对子例程的调用
substitute($_, 'foo', 'bar')
并且正则表达式模式只是第二个参数
您可以做的是存储正则表达式。替换的正则表达式部分是foo
,您可以说
my $pattern = qr/foo/;
s/$pattern/bar/;
但你真的应该解释你试图解决的问题,以便我们能够更好地帮助你
答案 2 :(得分:1)
在赋值中,你需要告诉Perl不要评估正则表达式而只是保留它。这就是qr的用途。
但你不能用全替换来做到这一点,这就是为什么Сухой27建议使用子程序。