<p>核心问题是,“是否有可能编写只捕获最长序列的正则表达式?”答案是“是”:</p>
<pre><code>import re
s = 'AGATC_AGATCAGATC_AGATCAGATCAGATC_AGATC_AGATCAGATC'
m = re.search(r'((?:AGATC)+)(?!.*\1)', s)
print m.group() if m else ''
#=> "AGATCAGATCAGATC"
</code></pre>
<p><a href="https://regex101.com/r/UQV4WI/4/" rel="nofollow noreferrer">Regex demo</a><sub><sup><</sup>“\<em>(ツ) </em>/'<sup>>;</sup></sub><a href="http://tpcg.io/cr8wluEW" rel="nofollow noreferrer">Python demo</a></p>
<p>Python的正则表达式引擎执行以下操作</p>
<pre><code>( begin capture group 1
(?:AGATC) match 'AGATC' in a non-capture group
+ execute the non-capture group 1+ times
) end capture group 1
(?! begin a negative lookahead
.* match 0+ characters
\1 match the content of capture group 1
) end the negative lookahead
</code></pre>
<p>对于上面的字符串<code>s</code>,将首先匹配<code>AGATC</code>,但负前瞻将发现<code>AGATC</code>是<code>AGATCAGATC</code>的第一部分,因此将拒绝临时匹配。然后<code>AGATCAGATC</code>将被匹配,但负前瞻将发现<code>AGATCAGATC</code>是<code>AGATCAGATCAGATC</code>的第一部分因此,这个临时匹配也将被拒绝。接下来,将匹配并接受<code>AGATCAGATCAGATC</code>,因为反向前瞻将不会在字符串的后面找到该匹配。(<code>re.findall</code>与<code>re.search</code>不同,它还将匹配字符串末尾的<code>AGATCAGATC</code>。)</p>
<p>如果使用了<code>re.findall</code>,则在最长的匹配之后可能会有多个匹配(请参见regex演示链接中的最后一个测试字符串),但匹配的长度从第一个到最后一个都不会减少。因此,使用<code>re.search</code>获得的第一个匹配是最长的匹配</p>