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

Hi: Is there a way I can substitute the ":" in the string below with a quote except when it is preceded by a "C" as in "C:\".
Engine4.2.0.5:prefix=PDE:path=C:\h\COE\COMP\PDE:status=installed:versi +onNumber=4.2.0.5:type=SOFTWARE-COE:
---confused

edited: Fri Aug 16 23:27:41 2002 by jeffa - code tags

  • Comment on Is there a way I can substitute for ":" except when it is preceded by a letter C
  • Download Code

Replies are listed 'Best First'.
Re: Is there a way I can substitute for ":" except when it is preceded by a letter C
by DamnDirtyApe (Curate) on Aug 16, 2002 at 23:18 UTC

    Use a negative look-behind assertion.

    $str =~ s/(?<!C):/"/g ;

    _______________
    DamnDirtyApe
    Those who know that they are profound strive for clarity. Those who
    would like to seem profound to the crowd strive for obscurity.
                --Friedrich Nietzsche
Re: Is there a way I can substitute for ":" except when it is preceded by a letter C
by tachyon (Chancellor) on Aug 16, 2002 at 23:20 UTC

    A negative look behind asserion will do the trick, see perlman:perlre on lookahead and look behind assertions both positive and negative for more details.

    $_ = 'c:--->j:a:p:h:,:'; s/(?<![cC]):/!/g; print;
    You could just use 'C' instead of the character class [cC] which makes this case insensitive. Of course you could also use /i at the end to do this but the character class was included in case you want to skip stuff like D:....

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: Is there a way I can substitute for ":" except when it is preceded by a letter C
by BrowserUk (Patriarch) on Aug 16, 2002 at 23:57 UTC

    Or if the phrase "negative lookbehind assertion" fills you with dread ...

    my $string = 'Engine4.2.0.5:prefix=PDE:path=C:\h\COE\COMP\PDE:status=installed:vers +ionNumber=4.2.0.5:type=SOFTWARE-COE:'; $string =~ s/([^C]):/$1'/g;

    ...will do it too.

    Update: ...almost:( See Tachon's post below for how to do it properly {sigh}.

    It reads; capture any single non-"C" char followed by a ":" and replace both by the captured char ($1) and the "'".


    What's this about a "crooked mitre"? I'm good at woodwork!

      But what if the string is ':foo'?

      s/([^C:]*):/$1'/g;

      cheers

      tachyon

      s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

        That's not quite right, the * makes it match even if there's 0 C's, turning all colons into apostrophes, not just the intended ones
        s/(^|[^C]):/$1'/g
        fixes that, but won't work if there is multiple colons in a row. A negative lookbehind is probably the only way to do this properly.

        --MrNobo1024
        s]]HrLfbfe|EbBibmv]e|s}w}ciZx^RYhL}e^print