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

Good evening

I don't know this one, and don't know if it's possible. I have a long string, let's say $str; I want to substitute all the pattern occurences (supose /\d+/) by one function with the match as argument. So assume, after each match, that the function is: sub add(){($v) = @_;return ($v*4);}

How can I do this?$str =~ s/\d+/&add($1)/gi; doesn't work...and seems terribly wrong...I've placed a simple function, but it can be much more complex.

Regards,

Kepler

EDIT: $str =~ s/\d+/&add($1)/ge; works... :)

Replies are listed 'Best First'.
Re: String replace with function
by GrandFather (Saint) on Sep 19, 2016 at 21:12 UTC

    Use the /e switch (see the end of the Modifiers section in perlre):

    use strict; use warnings; my $str = "1 2 345 23"; $str =~ s/(\d+)/add($1)/ge; print $str; sub add { my ($num) = @_; return $num + 10; }

    Prints:

    11 12 355 33

    Note that your sample was missing 's' in front of the first / that denotes substitution instead of match and was missing capture parenthesis in the match. Also, you don't need & to call a function, and in fact should (almost) never use that call syntax.

    Oh, and a sub called 'add' should add, not multiply. If you can't get simple names like that right you are going to cause a lot of grief for someone down the road!

    Premature optimization is the root of all job security
      Also, you don't need & to call a function, and in fact should (almost) never use that call syntax.

      To expand this bit, &function was the perl4 way to invoke subroutines. In perl5, &function

      • passes the current @_ to the invoked subroutine
      • overrides function prototypes

      Function prototypes? You should (almost) never use that... see perlsub.

      perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
Re: String replace with function
by shmem (Chancellor) on Sep 19, 2016 at 21:16 UTC
    How can I do this? $str =~ s/\d+/&add($1)/gi; doesn't work

    s/gi/ge - since i is case insensitive, e is eval ;-) And! capture to get $1:

    $str =~ s/(\d+)/&add($1)/ge;

    ...and &add() is soo perl4...

    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
Re: String replace with function
by Anonymous Monk on Sep 19, 2016 at 21:05 UTC
    #!/usr/bin/perl -l # http://perlmonks.org/?node_id=1172179 use strict; use warnings; sub add { 4 * shift; } $_ = '123 - 4 - 75 - 12'; print; s/(\d+)/ add($1) /ge; print;