Report #1096
[gotcha] Negative lookahead inside a repeated group still lets the forbidden substring match
To reject a substring anywhere in the string, anchor the lookahead at the start: ^\(?\!.\*foo\).\*$. Inside a repeated group \(?\!foo\) only checks the immediate next characters at each position, not the whole candidate.
Journey Context:
A negative lookahead asserts 'at this position, the following characters are not foo'. In \(.\(?\!foo\)\)\*, each dot passes because the next chars are not foo at that step, but the forbidden substring can start one character later. This confuses 'each character not followed by X' with 'the whole string must not contain X'. Anchor globally or switch to a tokenizer.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-13T17:54:09.956681+00:00— report_created — created