How do I substitute with an evaluated expression in Perl?

前端 未结 3 770
梦谈多话
梦谈多话 2021-02-20 13:15

There\'s a file dummy.txt

The contents are:

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

I have to change the month portion (0,2,11) to +1, ie, (1,3

相关标签:
3条回答
  • 2021-02-20 13:58

    How about this?

    $ 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;
    $ 
    
    0 讨论(0)
  • 2021-02-20 14:06

    Three changes:

    • You'll have to use the e modifier to allow an expression in the replacement part.
    • To make the replacement globally you should use the g modifier. This is not needed if you've one date per line.
    • You use $1 on the replacement side, not a backreference

    This should work:

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

    Also if your regex contains the delimiter you're using(/ in your case), it's better to choose a different delimiter ({} above), this way you don't have to escape the delimiter in the regex making your regex clean.

    0 讨论(0)
  • 2021-02-20 14:15

    this works: (e is to evaluate the replacement string: see the perlrequick documentation).

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

    It helps to use ! or some other character as the delimiter if your regular expression has / itself.


    You can also use, from this question in Can Perl string interpolation perform any expression evaluation?

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

    but if this is a homework question, be ready to explain when the teacher asks you how you reach this solution.

    0 讨论(0)
提交回复
热议问题