我有一个正在使用字符串运行的正则表列表,可以将它从一种格式转换为另一种格式。目前,所有这些正则表达式都存储在一个文件中。
通常,这很好用。如果它是" 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 {}或任何其他奇怪的东西,如果它会让我的生活更简单。
答案 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);