<h2>方法1:匹配并捕获你需要的,然后匹配其余的</h2>
<p>如果捕获组是在模式中定义的,则可以利用<code>re.findall</code>返回捕获组值。你只需要匹配你想忽略的东西,匹配并捕获你需要获得的东西。但是,当捕获组不匹配时,它也会返回空元素,这就是为什么<code>filter(None, results)</code>会派上用场的原因。你知道吗</p>
<p>这是一个<a href="https://ideone.com/J3pocG" rel="nofollow noreferrer">Python snippet</a>:</p>
<pre><code>import re
s = '''sweet (capture)
SWEETENED (capture)
not sweet (do not capture)
bitterly sweet (do not capture)'''
print(filter(None, re.findall(r'\b(?:bitterly|not)\s+sweet|\b(sweet\w*)\b', s, flags=re.I)))
# => ['sweet', 'SWEETENED']
</code></pre>
<p>在这里</p>
<ul>
<li><code>\b(?:bitterly|not)\s+sweet</code>-匹配整词<code>bitterly</code>或<code>not</code>,后跟1+空格和<code>sweet</code>子字符串</li>
<li><code>|</code>-或</li>
<li><code>\b(sweet\w*)\b</code>-一个完整的单词<code>sweet</code>,后面有任何其他单词字符(您可以使用自己的模式而不是<code>\w*</code>)</li>
<li><code>flags=re.I</code>-使模式不区分大小写。你知道吗</li>
</ul>
<p>参见<a href="https://regex101.com/r/FWrgIb/3" rel="nofollow noreferrer">regex demo</a>(由于代码的缘故,绿色文本将被保留)。你知道吗</p>
<h2>方法2:lookbehind不允许对输入进行太多控制</h2>
<p>关于消极的lookbehind方法的几句话:我认为这种方法不好,因为Python<code>re</code>中的lookbehind是固定宽度的,lookbehind中的所有替代方法必须具有相同的宽度。你知道吗</p>
<p>你可以用</p>
<pre><code>(?i)(?<!\bbitterly )(?<!\bnot )\bsweet\w*
</code></pre>
<p>(参见<a href="https://regex101.com/r/FWrgIb/2" rel="nofollow noreferrer">demo</a>),但是如果在<code>bitterly</code>或<code>sweet</code>之间有2或3个空格,则会失败。你知道吗</p>
<h2>方法3:使用PyPi regex模块的可变宽度lookback</h2>
<p>另一个有趣的解决方案是使用PyPi regex模块,您可以在其中使用可变宽度lookbehinds:</p>
<pre><code>import regex
s='''sweet (capture)
SWEETENED (capture)
not sweet (do not capture)
bitterly sweet (do not capture)'''
rx = r'(?<!\b(?:bitterly|not)\s+)\bsweet\w*\b'
print(regex.findall(rx, s, flags=regex.I))
# => ['sweet', 'SWEETENED']
</code></pre>
<p>参见<a href="http://rextester.com/MCTBA27718" rel="nofollow noreferrer">Python demo on REXTESTER</a>。你知道吗</p>
<p>只有在前面没有<code>\b(?:bitterly|not)\s+</code>模式时,才会匹配整个单词<code>sweet</code>(末尾有任何单词字符)。你知道吗</p>