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

Dear Monks,

perl -e ' $string="X*X*X*X"; \ $NEW=20; \ $string =~ s/(^|[\*])X([\*]|$)/${1}${NEW}${2}/g; \ print "$string\n";'

will gives :

20*X*20*X

It seems that after first match, the first '*' which was used by 1st match, doesn't count for the 2nd match ..

Is there any modifier or another way to replace all the 'X' at once ? any trick without executing this line twice ?

Thank you very much !

edit: Thank you all for your answers, the ?= works beautiful.. very useful! :D

Replies are listed 'Best First'.
Re: global string replace
by choroba (Cardinal) on Jun 07, 2019 at 09:35 UTC
    Use a look-ahead assertion. It looks ahead, but doesn't advance the position:
    s/(^|\*)X(?=\*|$)/$1$NEW/g # ~~~
    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
Re: global string replace
by jwkrahn (Abbot) on Jun 07, 2019 at 18:33 UTC
    perl -e' $string = "X*X*X*X"; $NEW = 20; $string =~ s/ (?: ^ | \* ) \K X (?= \* | $ ) /$NEW/xg; print "$string\n"; ' 20*20*20*20

      NB: The regex  \K operator (effectively, variable-width positive look-behind) is only available with Perl versions 5.10+.


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