<p>您可能需要使用单词边界标记<code>\b</code>。这是<code>\w</code>和<code>\W</code>之间转换的空匹配。如果希望关键字是文本字符串,则必须首先<a href="https://docs.python.org/3/library/re.html#re.escape" rel="nofollow noreferrer">escape</a>它们。可以使用<code>|</code>将所有内容组合成一个正则表达式:</p>
<pre><code>pattern = re.compile(r'\b(' + '|'.join(map(re.escape, keyword)) + r')\b')
</code></pre>
<p>或者</p>
<pre><code>pattern = re.compile(r'\b(?' + '|'.join(re.escape(k) for k in keyword) + r')\b')
</code></pre>
<p>计算匹配项现在变得更容易了,因为您可以使用<a href="https://docs.python.org/3/library/re.html#re.Pattern.finditer" rel="nofollow noreferrer">^{<cd5>}</a>而不是自己理解:</p>
<pre><code>matches = pattern.finditer(line)
</code></pre>
<p>由于每个匹配项都包含在一个组中,因此打印并不困难:</p>
<pre><code>result = "{:<15} {}".format(','.join(m.group() for m in matches), lineno)
</code></pre>
<p>或者</p>
<pre><code>result = "{:<15} {}".format(','.join(map(re.Match.group(), matches)), lineno)
</code></pre>
<p>当然,别忘了</p>
<pre><code>import re
</code></pre>
<p><strong>角盒</strong></p>
<p>如果关键字是具有相同前缀的彼此的子集,请确保先出现较长的关键字。例如,如果你有</p>
<pre><code>keyword = ['foo', 'foobar']
</code></pre>
<p>正则表达式将是</p>
<pre><code>\b(foo|foobar)\b
</code></pre>
<p>当您遇到一行中有<code>foobar</code>时,<code>foo</code>将与之成功匹配,然后与<code>\b'. This is documented behavior of</code>|`匹配失败。解决方案是在构造表达式之前,通过减小长度对所有关键字进行预排序:</p>
<pre><code>keywords.sort(key=len, reversed=True)
</code></pre>
<p>或者,如果可以使用非列表输入:</p>
<pre><code>keywords = sorted(keywords, key=len, reversed=True)
</code></pre>
<p>如果您不喜欢这个顺序,您可以在匹配后以其他顺序打印它们。你知道吗</p>