fix: SRT 解析器正确处理空文本字幕条目
旧正则把空文本条目与下一行合并,导致真实集成测试偶发 "译文条数 1439 != 原文 1440"(翻译补空/空字幕使条目被吞并)。 改为按时间轴行分块解析:序号缺省、空文本也独立计数,时间轴不丢失。
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user