kepler has asked for the wisdom of the Perl Monks concerning the following question:

Hi again

I'm replacing a pattern in a string like $data =~ s/(nr\d+)/calc\($1\);/gi;

I get pairs like "calc(nr45);". Next I want to replace only the remaining characters in the string like $data =~ s/(\d+)/$1*4/ge but without modifying the first ones. So if the string is "hello nr34 , 56, hi" I want to get "calc(nr34);" and modify "56" to 56*4... Is there a straight way to do this?

Thanks

Kepler

Replies are listed 'Best First'.
Re: String substitution
by Marshall (Canon) on Sep 20, 2016 at 01:56 UTC
    I'm not clear about what you want.
    How is this?:

    #!/usr/bin/perl use strict; use warnings; my $str = 'hello nr34 , 56, hi'; print "input string=$str\n"; $str =~ s/.*nr(\d+)([^\d]+)(\d+)(.*)/"calc(nr$1)$2".eval{$3*4}."$4";/e +; print "output string=$str\n"; __END__ Prints: input string=hello nr34 , 56, hi output string=calc(nr34) , 224, hi
    Please give some more example lines.
    I doubt that the above solves the "problem".
      $str =~ s/.*nr(\d+)([^\d]+)(\d+)(.*)/"calc(nr$1)$2".eval{$3*4}."$4";/e;

      FWIW: The separate  eval{$3*4} is not needed (although it does no harm) because the entire replacement expression is already being eval-ed:
          $str =~ s/.*nr(\d+)([^\d]+)(\d+)(.*)/"calc(nr$1);$2" . $3*4 . $4/e;
      (tested, and I also stuck the semicolon back where kepler seems to want it).


      Give a man a fish:  <%-{-{-{-<

Re: String substitution
by AnomalousMonk (Archbishop) on Sep 20, 2016 at 02:33 UTC

    Another way: each transformation gets its own substitution. This depends on discriminating between different types of  \d+ groups by their preceding patterns. Needs Perl version 5.10+ for the  \K regex operator; can be re-written to avoid using  \K (i.e., for pre-5.10) if needed.

    c:\@Work\Perl\monks>perl -wMstrict -le "use 5.010; ;; my $str = 'hello nr34,nr56,78, 98 , hi, 76'; print qq{'$str'}; ;; $str =~ s{ (nr\d+) }{calc($1);}xmsg; $str =~ s{ , \s* \K (\d+) }{ $1 * 4 }xmsge; print qq{'$str'}; " 'hello nr34,nr56,78, 98 , hi, 76' 'hello calc(nr34);,calc(nr56);,312, 392 , hi, 304'


    Give a man a fish:  <%-{-{-{-<

Re: String substitution
by kroach (Pilgrim) on Sep 20, 2016 at 15:15 UTC
    If I understood correctly, you want to replace (nr\d+) with "calc($1);" and multiply other occurences of \d+ by 4. This can be done with a single regex:
    $data =~ s/(nr)?(\d+)/$1 ? "calc($1$2);" : $2 * 4/ge;
    This will match both nr\d+ and \d+ and then decide how to replace it based on the presence of "nr".
Re: String substitution
by Anonymous Monk on Sep 20, 2016 at 03:36 UTC
    #!/usr/bin/perl # http://perlmonks.org/?node_id=1172192 use strict; use warnings; while(<DATA>) { print; s/(nr\d+)(?{"calc($1);"}) | (\d+)(?{4 * $2}) /$^R/gx; print; } __DATA__ hello nr34,nr56,78, 98 , hi, 76