fix: SRT 解析器正确处理空文本字幕条目

旧正则把空文本条目与下一行合并,导致真实集成测试偶发
"译文条数 1439 != 原文 1440"(翻译补空/空字幕使条目被吞并)。
改为按时间轴行分块解析:序号缺省、空文本也独立计数,时间轴不丢失。
This commit is contained in:
2026-09-05 22:32:15 +08:00
parent 2e8bbb15a4
commit fcdcfe020b
+35 -8
View File
@@ -109,23 +109,50 @@ def prompt_rule_candidates() -> list[Path]:
# SRT 解析(纯函数,供参考与产物共同使用) # SRT 解析(纯函数,供参考与产物共同使用)
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
_SRT_BLOCK_RE = re.compile( # 匹配 SRT 时间轴行(时间戳 --> 时间戳),作为条目边界。
r"(\d{2}:\d{2}:\d{2},\d{3})\s*-->\s*(\d{2}:\d{2}:\d{2},\d{3})\s*\n(.*?)(?=\n\s*\d+\s*\n|\Z)", _SRT_TIME_LINE_RE = re.compile(
re.DOTALL, r"(\d{2}:\d{2}:\d{2},\d{3})\s*-->\s*(\d{2}:\d{2}:\d{2},\d{3})",
) )
def parse_srt_entries(text: str) -> list[dict]: def parse_srt_entries(text: str) -> list[dict]:
"""解析 SRT 为 [{start, end, text}](秒为单位)。""" """解析 SRT 为 [{start, end, text}](秒为单位)。
按行分块:一个条目 = 序号行 + 时间轴行 + 若干文本行(可空)。即使文本为
空串(如翻译补空占位、空字幕)也计入一条,时间轴不丢失。"""
entries: list[dict] = [] entries: list[dict] = []
for match in _SRT_BLOCK_RE.finditer(text): lines = text.splitlines()
index = 0
while index < len(lines):
line = lines[index].strip()
# 跳过序号行与空行,找时间轴行。
if not line or not _SRT_TIME_LINE_RE.search(line):
index += 1
continue
match = _SRT_TIME_LINE_RE.search(line)
start = _ts_to_seconds(match.group(1))
end = _ts_to_seconds(match.group(2))
index += 1
# 收集后续非序号、非时间轴的文本行(可空/多行),直到空行或序号行。
text_parts: list[str] = []
while index < len(lines):
nxt = lines[index].strip()
if not nxt:
break # 空行:条目结束
if _SRT_TIME_LINE_RE.search(nxt):
break # 下一个时间轴:条目结束
if nxt.isdigit():
break # 下一个序号:条目结束
text_parts.append(nxt)
index += 1
entries.append( entries.append(
{ {
"start": _ts_to_seconds(match.group(1)), "start": start,
"end": _ts_to_seconds(match.group(2)), "end": end,
"text": match.group(3).strip().replace("\n", " "), "text": " ".join(text_parts),
} }
) )
index += 1
return entries return entries