From fcdcfe020bc303c67e4d0ee27b6be4527ecbcd4d Mon Sep 17 00:00:00 2001 From: catShark <1716967236@qq.com> Date: Sat, 5 Sep 2026 22:32:15 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20SRT=20=E8=A7=A3=E6=9E=90=E5=99=A8?= =?UTF-8?q?=E6=AD=A3=E7=A1=AE=E5=A4=84=E7=90=86=E7=A9=BA=E6=96=87=E6=9C=AC?= =?UTF-8?q?=E5=AD=97=E5=B9=95=E6=9D=A1=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 旧正则把空文本条目与下一行合并,导致真实集成测试偶发 "译文条数 1439 != 原文 1440"(翻译补空/空字幕使条目被吞并)。 改为按时间轴行分块解析:序号缺省、空文本也独立计数,时间轴不丢失。 --- tests/realdata_contract.py | 43 +++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/tests/realdata_contract.py b/tests/realdata_contract.py index 2284679..325539a 100644 --- a/tests/realdata_contract.py +++ b/tests/realdata_contract.py @@ -109,23 +109,50 @@ def prompt_rule_candidates() -> list[Path]: # SRT 解析(纯函数,供参考与产物共同使用) # --------------------------------------------------------------------------- -_SRT_BLOCK_RE = re.compile( - 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)", - re.DOTALL, +# 匹配 SRT 时间轴行(时间戳 --> 时间戳),作为条目边界。 +_SRT_TIME_LINE_RE = re.compile( + 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]: - """解析 SRT 为 [{start, end, text}](秒为单位)。""" + """解析 SRT 为 [{start, end, text}](秒为单位)。 + + 按行分块:一个条目 = 序号行 + 时间轴行 + 若干文本行(可空)。即使文本为 + 空串(如翻译补空占位、空字幕)也计入一条,时间轴不丢失。""" 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( { - "start": _ts_to_seconds(match.group(1)), - "end": _ts_to_seconds(match.group(2)), - "text": match.group(3).strip().replace("\n", " "), + "start": start, + "end": end, + "text": " ".join(text_parts), } ) + index += 1 return entries