<p>好吧,看起来问题出在<code>(?-i)</code>上,这很令人惊讶。内联修饰符语法的目的是让您可以将修饰符应用到regex的选定部分。至少,它们在大多数口味中都是这样工作的。在Python中,它们似乎总是修改整个regex,就像外部标志一样(<code>re.I</code>,<code>re.M</code>,等等)。替代的<code>(?i:xyz)</code>语法也不起作用。</p>
<p>另一方面,我认为没有任何理由使用三个单独的lookaheads,正如您在这里所做的那样:</p>
<pre><code>(?:(?!http://)(?!testing[0-9])(?!example[0-9]).)*?
</code></pre>
<p>或者他们在一起:</p>
<pre><code>(?:(?!http://|testing[0-9]|example[0-9]).)*?
</code></pre>
<hr/>
<p>编辑:我们似乎已经从regex为什么抛出异常的问题转移到了它为什么不工作的问题。我不确定我是否理解您的要求,但是下面的regex和替换字符串返回您想要的结果。</p>
<pre><code>s1 = re.sub(r'^((?!http://|testing[0-9]|example[0-9]).*?)(CODE[0-9]{3})(?!</a>)',
r'\g<1><a href="http://productcode/\g<2>">\g<2></a>', s)
</code></pre>
<p><strong><a href="http://ideone.com/3w1E3" rel="nofollow">see it in action one ideone.com</a></strong></p>
<p>这就是你想要的吗?</p>
<hr/>
<p>编辑:我们现在知道替换是在更大的文本中完成的,而不是在独立的字符串上。这使得问题变得更加困难,但是我们也知道完整的url(以<code>http://</code>开头的url)只出现在已经存在的锚元素中。这意味着我们可以将regex分成两个备选方案:一个用于匹配完整的<code><a>...</a></code>元素,另一个用于匹配目标字符串。</p>
<pre><code>(?s)(?:(<a\s+[^>]*>.*?</a>)|\b((?:(?!testing[0-9]|example[0-9])\w)*?)(CODE[0-9]{3}))
</code></pre>
<p>诀窍是使用函数代替静态字符串进行替换。每当regex与锚定元素匹配时,函数将在组(1)中找到它,并将其原封不动地返回。否则,它使用组(2)和组(3)来构建新的组。</p>
<p><strong><a href="http://ideone.com/65BOC" rel="nofollow">here's another demo</a></strong>(我知道这是可怕的代码,但我现在太累了,无法学习更像Python的方法。)</p>