home | list info | list archive | date index | thread index

Re: [OCLUG-Tech] Perl regex problem

Ian! D. Allen wrote:
On Mon, Mar 19, 2007 at 07:08:58PM -0400, Milan Budimirovic wrote:
I want to do a systematic search and replace of a word only where the word is NOT enclosed in double quotations.

#!/usr/bin/perl -w
while(<>){
        # surround quoted strings with unprintables
        s/("[^"]+")/\177$1\177/g;
        # split on the surrounded strings
        @a = split(/\177/);
        # loop over parts and avoid quoted pieces
        foreach $s ( @a ) {
                next if $s =~ /"/;
                $s =~ s/foo/bar/g;
        }
        # re-assemble and print
        print join("",@a);
}



Thanks to everyone who replied.

Ian's solution works.

As far as I understand it -- setting aside the theoretical limitations of regular expressions -- the difficulty with substituting in one line lies with the fact that for each instance of "foo" you would have to do a negative lookbehind to make certain that "foo" was not in inside an unclosed quotation mark that appears to its left. And Perl 5 does not support variable-width lookbehinds. But even the negative lookaheads I was trying in an effort to match unclosed quotation marks to the right did not seem to work:

 $string =~ s/foo(?!(([^"]*"[^"]*")*"[^"]*))/bar/;

Oh, well. :/

references