First order of business: If you read Writeup Formatting Tips you'll see that wrapping code in <code> ...... </code> tags is the way to prevent your code from getting mangled by the website's linking syntax. Following that protocol, your first regex must look like this:
s/^([^a]*)def/$1xyz/
...which can't possibly match "abcdef", because it anchors the match to the start of the string, and an 'a' character comes between the start of the string and the literal 'def', blocking the match. I guess that "works fine" because it does fail to match "abcdef".
The second regex is this:
s/^(?<!abc)def/$1xyz/
If your goal is to replace 'xyz' if it is not preceded by 'abc', that one would work, except for the anchoring to the beginning of the string. You're explicitly stating that you don't want to match 'def' if 'abc' comes before it. But by anchoring to the beginning of the string, and since assertions don't consume what they match, the only legal string would start with "def". Also, since you're not consuming the prefix (lookahead and lookbehind assertions don't consume), and since you're not capturing (there are no capturing parens), there's no need to have the $1 in the replacement.
By adding capturing parens to the beginning of the regex, with three wildcard metacharacers, it works out better. You'll find that s/^(...)(?<!abc)def/$1xyz/ rejects 'abcdef', but 'xxxdef' matches, becoming 'xxxxyz', which I think is what you want.
s/^(...)(?<!abc)def/$1xyz/;
Dave
In reply to Re: Regex question is this one of those look (ahead|behind)s ?
by davido
in thread Regex question is this one of those look (ahead|behind)s ?
by misterperl
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |