【问题标题】:Perl regexes from a file -- how to use $1?来自文件的 Perl 正则表达式——如何使用 $1?
【发布时间】:2015-04-16 05:34:48
【问题描述】:

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

通常,这可以正常工作。如果它将“Frog”读入$from,将“Toad”读入$to,那么“$string =~ s/$from/$to/”会根据需要将所有青蛙变成蟾蜍。

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

这是一个仅供家庭使用的脚本。如果可以让我的生活更简单,我很乐意使用 eval{} 或任何其他奇怪的东西。

【问题讨论】:

  • 我只想补充一点,(\d\d\d\d)-(\d\d)-(\d\d) 在我看来不太好,我宁愿使用(\d{4})-(\d{2})-(\d{2})

标签: regex perl


【解决方案1】:

要评估替换中的替换,请使用/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';

【讨论】:

    【解决方案2】:

    您可以使用以下内容:

    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);
    

    【讨论】:

    • 我更喜欢\d{n} :) 但说得好
    • @vol7ron,这不是我的代码。如果您对 OP 有风格评论,请告诉他,而不是我。
    • 不,我不想夸大答案,因为你和 Choroba 已经涵盖了重点。相反,我想向您指出,偏好是主观的,重要的是您偏好的客观品质。例如。 I prefer the second to the first since ...The benefit of the second over the first is that ... PCBP 不是关于偏好,而是更多关于成本/收益。
    • @vol7ron,我的意思是你应该将“我更喜欢\d{n}”的评论移到问题中,因为它与我或我的答案无关。
    • 我完全同意为什么是重要的部分。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多