为什么我不能在变量中存储正则表达式?

时间:2015-07-04 19:34:09

标签: regex perl

鉴于以下代码,

my $string = "foo";
my $regex = s/foo/bar/;
$string =~ $regex;
print $string, "\n";

我原本期望输出为bar,但它是foo。为什么会这样,我该如何解决这个问题?

请注意,在我的实际情况中,正则表达式更复杂,我实际上想要将其中的几个存储在哈希中(因此我可以编写类似$string =~ $rules{$key}的内容)。

3 个答案:

答案 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建议使用子程序。