合并SRT字幕不完整语句以提升DeepL翻译准确性(Python)
合并拆分的SRT字幕语句以提升翻译准确性
需求背景
我有一份SRT格式的视频字幕文件,计划用DeepL翻译,但字幕里的语句被拆分得支离破碎,导致翻译结果准确性不足。
目标功能
实现:如果某行语句未结束,就把后续行的对应内容合并到该行,直到语句完整,同时清空被合并行的文本,处理后效果示例如下。
原字幕内容
1 00:00:00,000 --> 00:00:13,680 Je vais mettre en direct sur l'hôtel comme ça on peut regarder les messages et tout. 2 00:00:13,680 --> 00:00:14,680 Ouais. 3 00:00:14,680 --> 00:00:20,080 Tiens je vais recevoir la notification Romain étant direct. 4 00:00:20,080 --> 00:00:22,720 Vas-y ouvrez le live. 5 00:00:22,720 --> 00:00:25,640 Ouais c'est bon on vous entend. 6 00:00:25,640 --> 00:00:26,640 Nice. 7 00:00:26,640 --> 00:00:28,480 Attends je vais présenter vite fait du coup, je vais attendre que tout le monde vienne. 8 00:00:28,480 --> 00:00:40,640 Salut Raphaël, salut Ismaël, salut Jean-Marc, bonjour à tous, bonjour Clément, bonjour 9 00:00:40,640 --> 00:00:41,640 Thierry. 10 00:00:41,640 --> 00:00:42,640 Bonjour à tous. 11 00:00:42,640 --> 00:00:44,640 Je ne sais pas s'ils nous entendent ou pas normalement. 12 00:00:44,640 --> 00:00:45,640 Si si ils t'entendent là. 13 00:00:45,640 --> 00:00:46,640 On va attendre. 14 00:00:46,640 --> 00:00:51,480 Limite on peut nous filmer en attendant que ça démarre vite fait, attends. 15 00:00:51,480 --> 00:00:53,360 Je vais vous filmer vous. 16 00:00:53,360 --> 00:00:57,520 Bon les gars juste pour faire une petite précision aujourd'hui on va avoir deux intervenants, 17 00:00:57,520 --> 00:01:02,560 on va avoir, je vais couper ma tête, on va avoir du coup CP Dropshipping, je pense que 18 00:01:02,560 --> 00:01:06,320 vous le connaissez, il a une chaîne YouTube, il a un compte Facebook assez suivi donc voilà 19 00:01:06,320 --> 00:01:11,520 avec un très beau t-shirt Balenciaga et aussi Jérémy donc on a deux Dropshippers qui pèsent 20 00:01:11,520 --> 00:01:16,960 assez lourd et voilà Jérémy c'est un administrateur du Discord et qui commence à faire tout 21 00:01:16,960 --> 00:01:21,520 est bien, qui commence à faire pas mal de souis, qui va venir habiter sur Malte bientôt 22 00:01:21,520 --> 00:01:22,520 je crois. 23 00:01:22,520 --> 00:01:25,520 On a regardé les vidéos d'avion là tout à l'heure. 24 00:01:25,520 --> 00:01:28,520 Il faudrait que je le ramène une semaine. 25 00:01:28,520 --> 00:01:30,320 Ah merde, je me suis trompé.
处理后预期效果
1 00:00:00,000 --> 00:00:13,680 Je vais mettre en direct sur l'hôtel comme ça on peut regarder les messages et tout. 2 00:00:13,680 --> 00:00:14,680 Ouais. 3 00:00:14,680 --> 00:00:20,080 Tiens je vais recevoir la notification Romain étant direct. 4 00:00:20,080 --> 00:00:22,720 Vas-y ouvrez le live. 5 00:00:22,720 --> 00:00:25,640 Ouais c'est bon on vous entend. 6 00:00:25,640 --> 00:00:26,640 Nice. 7 00:00:26,640 --> 00:00:28,480 Attends je vais présenter vite fait du coup, je vais attendre que tout le monde vienne. 8 00:00:28,480 --> 00:00:40,640 Salut Raphaël, salut Ismaël, salut Jean-Marc, bonjour à tous, bonjour Clément, bonjour Thierry. 9 00:00:40,640 --> 00:00:41,640 10 00:00:41,640 --> 00:00:42,640 Bonjour à tous. 11 00:00:42,640 --> 00:00:44,640 Je ne sais pas s'ils nous entendent ou pas normalement. 12 00:00:44,640 --> 00:00:45,640 Si si ils t'entendent là. 13 00:00:45,640 --> 00:00:46,640 On va attendre. 14 00:00:46,640 --> 00:00:51,480 Limite on peut nous filmer en attendant que ça démarre vite fait, attends. 15 00:00:51,480 --> 00:00:53,360 Je vais vous filmer vous. 16 00:00:53,360 --> 00:00:57,520 Bon les gars juste pour faire une petite précision aujourd'hui on va avoir deux intervenants, on va avoir, je vais couper ma tête, on va avoir du coup CP Dropshipping, je pense que vous le connaissez, il a une chaîne YouTube, il a un compte Facebook assez suivi donc voilà avec un très beau t-shirt Balenciaga et aussi Jérémy donc on a deux Dropshippers qui pèsent assez lourd et voilà Jérémy c'est un administrateur du Discord et qui commence à faire tout est bien, qui commence à faire pas mal de souis, qui va venir habiter sur Malte bientôt je crois. 17 00:00:57,520 --> 00:01:02,560 18 00:01:02,560 --> 00:01:06,320 19 00:01:06,320 --> 00:01:11,520 20 00:01:11,520 --> 00:01:16,960 21 00:01:16,960 --> 00:01:21,520 22 00:01:21,520 --> 00:01:22,520 23 00:01:22,520 --> 00:01:25,520 On a regardé les vidéos d'avion là tout à l'heure. 24 00:01:25,520 --> 00:01:28,520 Il faudrait que je le ramène une semaine. 25 00:01:28,520 --> 00:01:30,320 Ah merde, je me suis trompé.
已尝试代码
import re file = open('files/FINAL/v23FINAL.srt') content = file.readlines() new = '' i = 2 max = len(content) - 1 while i < max : now = str(content[i][-2]) next = str(content[i+4][-2]) print(now + '\n' + next) if now != '.' or now != '?' or now != '!': for j in range(len(content[i+4])): if content[i+4][j] == '.' or content[i+4][j] == '?' or content[i+4][j] == '!': print(content[i+4][0:j+1]) print(content[i+4][j+2:len(content)-2]) break i += 4 else: new += content[i] new += content[i+1] new += content[i+2] new += '\n' i += 4 with open('newText.srt', 'a') as n: n.write(new)
Python解决方案
下面是完整的实现代码,核心逻辑是先解析SRT字幕为结构化数据,再合并未结束的语句,最后重新生成符合格式的SRT文件:
def parse_srt(file_path): """解析SRT文件,返回字幕条目列表,每个条目是包含序号、时间轴、文本的字典""" subtitles = [] with open(file_path, 'r', encoding='utf-8') as f: lines = [line.rstrip('\n') for line in f] i = 0 while i < len(lines): if lines[i].strip().isdigit(): idx = lines[i].strip() time_line = lines[i+1].strip() text_lines = [] j = i+2 while j < len(lines) and lines[j].strip() != '': text_lines.append(lines[j].strip()) j += 1 subtitles.append({ 'index': idx, 'time': time_line, 'text': ' '.join(text_lines) }) i = j + 1 else: i += 1 return subtitles def merge_split_sentences(subtitles): """合并未结束的语句,清空被合并条目的文本""" merged_subs = subtitles.copy() i = 0 while i < len(merged_subs): current_text = merged_subs[i]['text'] # 检查当前文本是否以句末标点结尾 if not current_text.endswith(('.', '?', '!')) and i < len(merged_subs)-1: next_idx = i + 1 # 持续合并后续条目直到找到句末标点 while next_idx < len(merged_subs): next_text = merged_subs[next_idx]['text'] merged_subs[i]['text'] += ' ' + next_text merged_subs[next_idx]['text'] = '' if next_text.endswith(('.', '?', '!')): break next_idx += 1 i = next_idx i += 1 return merged_subs def write_srt(subtitles, output_path): """将处理后的字幕条目写入SRT文件""" with open(output_path, 'w', encoding='utf-8') as f: for sub in subtitles: f.write(sub['index'] + '\n') f.write(sub['time'] + '\n') f.write(sub['text'] + '\n\n') # 主流程 input_srt = 'files/FINAL/v23FINAL.srt' output_srt = 'merged_subtitles.srt' subs = parse_srt(input_srt) merged_subs = merge_split_sentences(subs) write_srt(merged_subs, output_srt)
代码说明
parse_srt函数:把SRT文件的内容解析成结构化的字典列表,每个字典包含字幕的序号、时间轴和文本,方便后续处理。merge_split_sentences函数:遍历字幕条目,检查当前条目的文本是否以句末标点(.?!)结尾,如果没有,就把后续条目的文本合并进来,并清空后续条目的文本,直到遇到包含句末标点的条目为止。write_srt函数:把处理后的结构化字幕数据重新写入成标准的SRT格式文件。
使用时只需要修改input_srt和output_srt的路径即可。
内容的提问来源于stack exchange,提问作者Ömer Work
相关产品推荐
相关产品推荐

