Most of the time, you can avoid variable length lookbehinds by using \K
.
s/(?<=foo.*)bar/moo/s;
would be
s/foo.*\Kbar/moo/s;
Anything up to the last \K
encountered is not considered part of the match (e.g. for the purposes of replacement, $&
, etc)
Negative lookbehinds are a little trickier.
s/(?<!foo.*)bar/moo/s;
would be
s/^(?:(?!foo).)*\Kbar/moo/s;
because (?:(?!STRING).)*
is to STRING
as [^CHAR]*
is to CHAR
.
If you’re just matching, you might not even need the \K
.
/foo.*bar/s
/^(?:(?!foo).)*bar/s