<p>以下仅处理每个<code>'.srt'</code>文件的第3行。它可以很容易地适应处理其他行和/或其他文件</p>
<pre><code>import os
import re
from glob import glob
with open('words.txt') as f:
keep_words = {line.strip().lower() for line in f}
for filename_in in glob('*.srt'):
filename_out = f'{os.path.splitext(filename_in)[0]}_new.srt'
with open(filename_in) as fin, open(filename_out, 'w') as fout:
for i, line in enumerate(fin):
if i == 2:
parts = re.split(r"([\w']+)", line.strip())
parts[1::2] = [w if w.lower() in keep_words else '*' for w in parts[1::2]]
line = ''.join(parts) + '\n'
fout.write(line)
</code></pre>
<p>结果(对于您作为示例给出的<code>subtitle.rst</code>):</p>
<pre><code>! cat subtitle_new.rst
2
00:00:13,000 > 00:00:15,000
People with * * are good.
</code></pre>
<p>备选方案:只需在词汇表外的单词旁边添加一个<code>'*'</code>:</p>
<pre><code># replace:
# parts[1::2] = [w if w.lower() in keep_words else '*' for w in parts[1::2]]
parts[1::2] = [w if w.lower() in keep_words else f'{w}*' for w in parts[1::2]]
</code></pre>
<p>然后输出为:</p>
<pre><code>2
00:00:13,000 > 00:00:15,000
People with cleidocranial* dysplasia* are good.
</code></pre>
<p>说明:</p>
<ul>
<li>第一个<code>open</code>用于读入所有想要的单词,确保它们是小写的,并将它们放入<code>set</code>(用于快速成员资格测试)</li>
<li>我们使用<code>glob</code>查找以<code>'.srt'</code>结尾的所有文件名</li>
<li>对于每个这样的文件,我们构造一个从中派生的新文件名<code>'..._new.srt'</code></li>
<li>我们读取所有行,但只修改行<code>i == 2</code>(即第三行,因为默认情况下<code>enumerate</code>从0开始)</li>
<li><code>line.strip()</code>删除尾随的换行符</li>
<li>我们本可以使用<code>line.strip().split()</code>将行拆分为单词,但它会将<code>'good.'</code>作为最后一个单词;不太好。使用的正则表达式通常用于拆分单词(特别是,它在单引号中留下如<code>"don't"</code>;它可能是您想要的,也可能不是您想要的,当然可以随意调整)</li>
<li>我们使用捕获组拆分<code>r"([\w']+)"</code>而不是对非单词字符进行拆分,这样我们就有了两个单词以及在<code>parts</code>中分隔它们的内容。例如,<code>'People, who are good.'</code>变成了<code>['', 'People', ', ', 'who', ' ', 'are', ' ', 'good', '.']</code></li>
<li>单词本身是<code>parts</code>的每一个其他元素,从索引1开始</li>
<li>如果单词的小写形式不是^{<cd21>,我们将其替换为<code>'*'</code></li>
<li>最后,我们重新组装该行,并通常将所有行输出到新文件</li>
</ul>