Why does Negative Lookahead times out with And/Or Pipe
<p>I have an And/Or regex i.e (PatternA|PatternB) in which I only take PatternA if PatternB does not exist (PatternB always comes after PatternA but is more important) so I put a negative lookahead in the PatternA Pipe.</p>

<p>This works on shorter text blocks:</p>

<p><a href="https://regex101.com/r/bU6cU6/5" rel="nofollow">https://regex101.com/r/bU6cU6/5</a></p>

<p>But times out on longer text blocks:</p>

<p><a href="https://regex101.com/r/bU6cU6/2" rel="nofollow">https://regex101.com/r/bU6cU6/2</a></p>

<p>What I don't understand is if I put PatternA with the Neg Look ahead alone in the same long text block it takes only 32 steps to reject it:</p>

<p><a href="https://regex101.com/r/bU6cU6/3" rel="nofollow">https://regex101.com/r/bU6cU6/3</a></p>

<p>and if I put PatternB alone in the same long text block it only takes 18 steps to accept it:</p>

<p><a href="https://regex101.com/r/bU6cU6/4" rel="nofollow">https://regex101.com/r/bU6cU6/4</a></p>

<p>So I am not sure why it is taking 100,000+/timeout to first reject (32 steps) then accept (18 steps) with the pipes. Is there another/better way to construct so it checks PatternA first than PatternB because now it is doing something I don't understand to go from 50 steps to 100k +.</p>

<p>Unanchored lookarounds used with a "global" regex (matching several occurrences) cause too much legwork, and are inefficient. They should be "anchored" to some concrete context. Often, they are executed at the beginning (lookaheads) or end (lookbehinds) of the string.</p>

<p>In your case, you may "anchor" it by placing after <code>Option1:</code> to ensure it is only executed after <code>Option1:</code> is aready matched.</p>

<pre><code>Option1:(?!.*Option2)\*.*?(?P&lt;Capture&gt;Bob|David|Ted|Alice)|\*Option2 (?P&lt;Capture2&gt;Juan)
        ^^^^^^^^^^^^^
</code></pre>

<p>See <a href="https://regex101.com/r/vS6eJ2/1" rel="nofollow">this regex demo</a></p>

<p>Some more answers:</p>

<blockquote>
  <p>What I don't understand is if I put PatternA with the Neg Look ahead alone in the same long text block it takes only 32 steps to reject it</p>
</blockquote>

<p>Yes, but you tested it with internal optimizations ON. Disable them and you will see</p>

<p><a href="http://i.stack.imgur.com/ieiNe.png" rel="nofollow"><img src="http://i.stack.imgur.com/ieiNe.png" alt="enter image description here"></a></p>

<blockquote>
  <p>if I put PatternB alone in the same long text block it only takes 18 steps to accept it:</p>
</blockquote>

<p>The match is found as expected, in a very efficient way:</p>

<p><a href="http://i.stack.imgur.com/5t8XD.png" rel="nofollow"><img src="http://i.stack.imgur.com/5t8XD.png" alt="enter image description here"></a></p>

python regex timeout negative-lookahead