【问题标题】:How do I substitute with an evaluated expression in Perl?如何用 Perl 中的评估表达式替换?
【发布时间】:2010-10-15 05:49:20
【问题描述】:

有一个文件 dummy.txt

内容是:

 9/0/2010
 9/2/2010
 10/11/2010

我必须将月份部分 (0,2,11) 更改为 +1,即 (1,3,12) 我将替换正则表达式编写如下

 $line =~ s/\/(\d+)\//\/\1+1\//;

正在打印中

9/0+1/2010
9/2+1/2010
10/11+1/2010

如何使它添加 - 3 数字而不是执行字符串连接? 2+1??

【问题讨论】:

    标签: regex perl substitution


    【解决方案1】:

    三个变化:

    • 您必须使用e 修饰符 允许在 更换零件。
    • 进行全局替换 您应该使用 g 修饰符。如果您每行有一个日期,则不需要
    • 您在替换端使用$1,而不是反向引用

    这应该可行:

    $line =~ s{/(\d+)/}{'/'.($1+1).'/'}eg;
    

    此外,如果您的正则表达式包含您正在使用的分隔符(在您的情况下为/),最好选择不同的分隔符(上面的{}),这样您就不必在正则表达式使您的正则表达式干净。

    【讨论】:

    • 太棒了!,它起作用了——如果你不介意你能解释一下 s{} 语法吗——我的意思是可以用 s/ 而不是 s{ 来实现它
    • @OP:我已经更新了我的答案。 s/// 等价于s{}{},只是它使用了不同的分隔符,可以避免转义那些/
    • 虽然不是必需的,但在正则表达式中使用 'x' 修饰符可以大大提高它们的可读性: s{ / (\d+) / }{ '/' 。 ($1+1) 。 '/'}egx
    【解决方案2】:

    这个怎么样?

    $ cat date.txt 
    9/0/2010
    9/2/2010
    10/11/2010
    $ perl chdate.pl 
    9/1/2010
    9/3/2010
    10/12/2010
    $ cat chdate.pl 
    use strict;
    use warnings;
    
    open my $fp, '<', "date.txt" or die $!;
    
    while (<$fp>) {
        chomp;
        my @arr = split (/\//, $_);
        my $temp = $arr[1]+1;
        print "$arr[0]/$temp/$arr[2]\n";
    }
    
    close $fp;
    $ 
    

    【讨论】:

    • 感谢这种方法 - 我将继续探索 perl - 我已经接受了另一个答案,因为它用一行来解决
    • 是的,那些答案肯定更好,我也不知道表达式。
    【解决方案3】:

    这可行:(e 是评估替换字符串:请参阅perlrequick 文档)。

    $line = '8/10/2010';
    $line =~ s!/(\d+)/!('/'.($1+1).'/')!e;
    
    print $line;
    

    如果您的正则表达式本身具有/,则使用! 或其他字符作为分隔符会有所帮助。


    您也可以使用Can Perl string interpolation perform any expression evaluation?中的这个问题

    $line = '8/10/2010';
    $line =~ s!/(\d+)/!("/@{[$1+1]}/")!e;
    
    print $line;
    

    但如果这是一个家庭作业问题,当老师问你如何达到这个解决方案时,请准备好解释。

    【讨论】:

    • 感谢您提及分隔符!
    • 哦,不,不!,不是家庭作业问题,我会向您解释 - 我的解决方案有效,但我想知道是否有更好的方法。我正在创建一个跟踪所有使用过应用程序的用户的数据库。身份验证系统是外部的 - 但是它为每个登录写入一个单独的文件。我试图通过捕获文件创建时间并以 SQL Server DATETIME 格式插入来获取登录时间。我写的第一个 perl 程序错过了这个重要的事实——所以大多数日期都是 0/0/2010 格式(与 DATETIME 不兼容)。再次运行 Perl 程序并进行更改是昂贵的
    猜你喜欢
    • 1970-01-01
    • 2011-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-28
    相关资源
    最近更新 更多