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

Hi all, I need to replace all instances of {{ and {} in a string with {empty{ and {empty}.
I tried:
    $foo =~ s/\{\{/\{empty\{/g;  #to do {{
    $foo =~ s/\{\}/\{empty\}/g; #to do {}

But on something like this:
    $foo = "{john{david{mary{{{{martin}"
It only replaces {{ once. So I get the following:
"{john{david{mary{empty{{{martin}" instead of "{john{david{mary{empty{empty{empty{martin}"

Now I've reworked these to lines to the following:
while ($line =~ /\{\{/|/\{\}/){ $line =~ s/\{\{/\{NA\{/; $line =~ s /\{\}/\{NA\}/; };
Everything works fine, but does anyone know if there is a more efficient (less code) way of achieving the proper result? Thanks for your time.

Replies are listed 'Best First'.
Re: Help with Substitution
by japhy (Canon) on Jun 28, 2001 at 20:28 UTC
      Thank you, the code worked perfectly. I will be reading up on "look-ahead". Thanks again everyone.
Re: Help with Substitution
by bikeNomad (Priest) on Jun 28, 2001 at 20:15 UTC
    How about this:

    $foo = "{john{david{mary{{{{martin}"; 1 while $foo =~ s/{([{}])/{empty$1/g; print "$foo\n";
Re: Help with Substitution
by malloc (Pilgrim) on Jun 28, 2001 at 20:24 UTC
    I have a related question, would this case where you are only seem to be dealing with strings, would multiple tr 's be more efficient(more code & less cpu)?
    -malloc

      tr/// would not work in this case, because the questioner is not replacing char for char. He is replacing a pattern with a different pattern.
Re: Help with Substitution
by TravelByRoad (Acolyte) on Jun 28, 2001 at 21:47 UTC
    I tested your original code, and got results different than what you report:

    > {john{david{mary{empty{{empty{martin}

    This is the result my test got, and what I would expect (correct behavior) from that regex code. If you really want ALL double { out, then the lookahead code suggested above would seem to be the optimal way.

    TbR

      OK, I give up: why does the expression only replace the {{ once?

        Because the regex starts where it left off and it already matched the first two characters of "{{{" to become "{empty{{" so it starts looking at the third "{" and, from there, never finds "{{".

        *{john{david{mary{{{martin} ^ Start there looking for {{ or {} {john{david{mary*{{{martin} ^ stop here, having found a match {john{david{mary{empty{*{martin} ^ resume here no {} nor {{ left to find from there

        Update: Unless you are asking why it would only match once against "{{{{", in which case the answer is "it doesn't; it matches twice".

                - tye (but my friends call me "Tye")