来自文件的Perl正则表达式 - 如何使用$ 1?

时间:2015-04-15 20:58:51

标签: regex perl

我有一个正在使用字符串运行的正则表列表,可以将它从一种格式转换为另一种格式。目前,所有这些正则表达式都存储在一个文件中。

通常,这很好用。如果它是" Frog"进入$,来自" Toad"进入$ to,然后" $ string = ~s / $ from / $ to /"根据需要将所有青蛙变成蟾蜍。

现在我想做一些比较棘手的事情:给出约会" 2015-04-15",我想将其更改为" 04/2015",再次从文件中读取。如果我加载"(\ d \ d \ d \ d) - (\ d \ d) - (\ d \ d)"进入$和$&2; $ 2 / $ 1"进入$ to,这不起作用:它用文字字符串" $ 2 / $ 1"替换日期,输出中有实际的美元符号。我需要做什么?

这是仅供家庭使用的脚本。我很高兴使用eval {}或任何其他奇怪的东西,如果它会让我的生活更简单。

2 个答案:

答案 0 :(得分:3)

要评估替换中的替换,请使用/ee修饰符。这将执行替换表达式($to)作为Perl代码,并将其结果($to的值)传递给eval EXPR。因此,$to需要包含有效的Perl代码,这意味着您必须引用表达式以避免将其评估为除法。

my $in = '2015-04-15';
my $expected = '04/2015';

my $from = '(\d\d\d\d)-(\d\d)-(\d\d)';
my $to = '"$2/$1"';

$in =~ s/$from/$to/ee;
print $in eq $expected ? 'YES' : 'NO';

答案 1 :(得分:1)

您可以使用以下内容:

my $from = '(\d\d\d\d)-(\d\d)-(\d\d)';
my $to = '"$2/$1"';
my $string = '2015-04-15';
$string =~ s/$from/$to/ee;

上述内容简称如下:

my $from = '(\d\d\d\d)-(\d\d)-(\d\d)';
my $to = '"$2/$1"';
my $string = '2015-04-15';
$string =~ s/$from/ eval($to) /e;

我更喜欢第二个到第一个,因为它并没有隐藏使用eval(EXPR)的事实。但是,上述两种沉默错误,所以以下情况会更好:

my $from = '(\d\d\d\d)-(\d\d)-(\d\d)';
my $to = '"$2/$1"';
my $string = '2015-04-15';
$string =~ s/$from/ my $r = eval($to); die $@ if $@; $r /e;

但正如您所看到的,上述所有内容都允许执行任意Perl代码。以下将更安全:

use String::Substitution qw( gsub_modify );

my $from = '(\d\d\d\d)-(\d\d)-(\d\d)';
my $to = '$2/$1';
my $string = '2015-04-15';
gsub_modify($string, $from, $to);