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

Dears,

Why the following code would replace 1 characters set out of 2, I don't get it..?

for (@lines) { s/\|\|/\|#MI\|/g }

or for (@lines) { s/        /    #MI    /g }

Input: EST07|E9028;CP392;ALLOC_CP392|R2021||||||||||||0.46458

Output: EST07|E9028;CP392;ALLOC_CP392|R2021|#MI||#MI||#MI||#MI||#MI||#MI|0.46458

Expected: EST07|E9028;CP392;ALLOC_CP392|R2021|#MI|#MI|#MI|#MI|#MI|#MI|#MI|#MI|#MI|#MI|#MI|0.46458

So my workaround is the following:

for (@lines) { s/\|\|/\|#MI\|/g }

for (@lines) { s/\|\|/\|#MI\|/g }

or for (@lines) { s/        /    #MI    /g } for (@lines) { s/        /    #MI    /g } Thank you for your wisdom. SRX

Replies are listed 'Best First'.
Re: Substitution is replacing one character set out of two
by hippo (Archbishop) on Apr 01, 2022 at 11:19 UTC

    A lookahead should do the trick:

    use strict; use warnings; use Test::More tests => 1; my $have = 'EST07|E9028;CP392;ALLOC_CP392|R2021||||||||||||0.46458'; my $want = 'EST07|E9028;CP392;ALLOC_CP392|R2021|#MI|#MI|#MI|#MI|#MI|#M +I|#MI|#MI|#MI|#MI|#MI|0.46458'; $have =~ s/\|(?=\|)/|#MI/g; is $have, $want;

    🦛

      Thank you for the workaround but why such a behavior?

        Without the lookahead your search and replace consumes the second pipe, so subsequent attempts to match will start beyond it. I would not call it a workaround - it's a valid solution to the task.


        🦛

Re: Substitution is replacing one character set out of two
by choroba (Cardinal) on Apr 01, 2022 at 10:58 UTC
    Please, you <code>...</code> tags for readability.

    What input do you have? What output do you get and how does it differ from your expectations?

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]