如何用正则替换字幕文件单词末尾的大写I为小写l(含忽略列表)
解决.srt字幕中单词末尾大写I替换为小写l(含标点处理+忽略指定词汇)
现有代码的问题分析
你的代码处理带标点的单词失效,核心原因有两个:
- 用
split(" ")拆分单词太死板,且通过endswith("I")判断时,完全没考虑单词末尾带标点的情况(比如belI?、hilI,)——这些单词的I后面跟着标点,不会被判定为以I结尾,自然不会进入替换逻辑。 - 就算跳过判断直接替换,
re.sub(r'I\b', 'l', i)的\b虽然能识别单词边界,但拆分后的单词已经带标点,前面的判断逻辑已经把这类单词过滤掉了,根本到不了替换步骤。
解决方案:整行正则替换(兼顾标点+忽略指定词汇)
直接对整行文本做正则匹配替换,不用拆分单词,同时通过正则断言排除需要忽略的词汇。
完整代码
import re # 需要忽略的词汇列表 ignore_list = ["FBI"] # 构建忽略词汇的正则负向断言,避免替换这些词里的I ignore_pattern = r"(?!" + r"|".join([re.escape(word) + r"\b" for word in ignore_list]) + r")" # 匹配规则:单词末尾的大写I,后面可以跟标点或行尾,且不在忽略词汇中 replace_regex = re.compile(rf"{ignore_pattern}\bI(?=[^\w]|$)") # 输入输出文件路径 input_file = "your_input.srt" output_file = "fixed_subtitle.srt" with open(input_file, "r", encoding="utf-8") as in_f, open(output_file, "w", encoding="utf-8") as out_f: for line in in_f: # 跳过字幕序号和时间轴行(这些行无需要替换的内容) stripped_line = line.strip() if stripped_line.isdigit() or "-->" in stripped_line: out_f.write(line) continue # 执行替换并写入结果 fixed_line = replace_regex.sub("l", line) out_f.write(fixed_line)
代码说明
- 忽略词汇处理:
ignore_pattern把忽略列表中的词汇转成正则负向先行断言,确保像FBI这类词里的I不会被替换。 - 匹配规则:
\bI(?=[^\w]|$)匹配单词边界后的大写I,(?=[^\w]|$)用来兼容I后面带标点(逗号、问号等)或行尾的情况,完美覆盖你遇到的带标点单词场景。 - 效率优化:跳过字幕的序号和时间轴行,避免无意义的正则匹配。
- 文件读写:直接生成修复后的字幕文件,比打印结果更实用。
测试效果
针对你提供的示例字幕,处理后会得到:
1 00:00:14, 391 --> 00:00:15, 976 He he'll crawl Interdimensional, 2 00:00:17, 352 --> 00:00:18, 353 Who, are you a bell? l? l am on a hill, 3 00:00:17, 352 --> 00:00:18, 353 l walking up hi'll, and roll all the way down. 4 00:00:17, 352 --> 00:00:18, 353 l fell and we'll go again to the FBI.
内容的提问来源于stack exchange,提问作者bob_the_bob
相关产品推荐
相关产品推荐

