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

Simple problem: A big string ie

$_="blah blah blah A blah blah blah B(A) blah blah blah"

Replace all the "A"s with "Z"s:

s/A/Z/g;

Easy. But what if I _don't_ want to replace "B(A)"'s?
This is just an example. In my case B and A are more complicated - what I really need to know is how to do "look behind" in REs.

Wisdom, oh enlightened ones?

Replies are listed 'Best First'.
Re: look behind in REs
by vroom (His Eminence) on Apr 06, 2000 at 08:40 UTC
Re: look behind in REs
by japhy (Canon) on Apr 06, 2000 at 15:42 UTC
    Perl regular expressions allow for look-ahead and look-behind assertions in both the positive and negative sense. However, look-behind assertions are a bit annoying, because they cannot be patterns of non-constant length. Meaning you can't say
    print "whatever" if "foobar" =~ /(?<=o*)b/; # print whatever if foobar has a b preceeded by any number of o's
    You'll have to work around it somehow.
Re: look behind in REs
by chromatic (Archbishop) on Apr 06, 2000 at 18:47 UTC
    You *could* do it in three steps:
    my $string = "AAbfwercB(A)fjklASZaB(A)xvASABAB(A)gfdaZAA"; my @chunks = split(/B\(A\)/, $_); $_ =~ tr/A/Z/ foreach @chunks; $string = join 'B(A)', @chunks;
    My guess is that it's a little slow, though. I'd reverse $string first, myself.
Re: look behind in REs
by zodiac (Beadle) on Apr 06, 2000 at 17:28 UTC
    the following should work:
    s/([^([]])A([^)[]])/$1Z$2/;

    it replaces "A" without brackets with "Z". if there are brackets the regex does not match. thus no replacement.
Re: look behind in REs
by jbert (Priest) on Apr 06, 2000 at 15:57 UTC
    Ugly but works (for some definition of 'works'):
    $line =~ s/BA/XXXXsome magic sequenceXXXX/g; $line =~ s/A/Z/g; $line =~ s/XXXXsome magic sequenceXXXX/BA/g;