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. :/