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

#!/usr/bin/perl while(<DATA>){ s/\%EX\%/TOdelete/; s/\%BC\%/TOdelete/; s/\%EC\%/TOdelete/; print $_; } __DATA__ %BX% HI %EX% %BC% %EC%
How to merge the above code to single statement

Replies are listed 'Best First'.
Re: merge code
by BrowserUk (Patriarch) on Sep 01, 2009 at 07:39 UTC

    Assuming that if multiple instances of any one of those targets, appeared in the same line, they should all be replaced:

    s[(%(?:EX|EC|BC)\%)][TOdelete]g, print while <DATA>; ## Adjusted

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: merge code
by moritz (Cardinal) on Sep 01, 2009 at 08:07 UTC
    As already hinted by BrowserUk it's not easy to put the exact same semantics into a single statement.

    The three substitutions replace the first occurrence of each of the patterns. I don't even know if that's possible in a regex.

    Consider the case that input data is %EX% %EC% %EX% %BC% - the original code prodcues TOdelete TOdelete %EX% TOdelete for that.

    If you really need that behaviour, you can use this:

    while(<DATA>){ my %seen; s/(%(?:EX|BC|EC)%)/$seen{$1}++ ? $1 : "TOdelete" /ge; print $_; }
    Perl 6 - links to (nearly) everything that is Perl 6.
Re: merge code
by ambrus (Abbot) on Sep 01, 2009 at 11:04 UTC

    Perhaps tell us what's wrong with it begin multiple statements, then we could help address that problem.

Re: merge code
by JavaFan (Canon) on Sep 01, 2009 at 09:58 UTC
    Personally, I would leave it as is. If you worry about the duplication of the replacement part, put that into a variable. The three substitutions are simpler than the combined pattern. And it might even be faster (as it's more likely the optimizer can do it all in the 3-statement case than in the big regexp case).
Re: merge code
by Anonymous Monk on Sep 01, 2009 at 07:23 UTC
Re: merge code
by bichonfrise74 (Vicar) on Sep 01, 2009 at 18:31 UTC
    Can you use something like this?
    #!/usr/bin/perl use strict; while(<DATA>){ s/\%EX\%|\%BC\%|\%EC\%/TOdelete/g; print; } __DATA__ %BX% HI %EX% %BC% %EC%