fix(metainfo): improve regex for episode range recognition with end markers

This commit is contained in:
jxxghp
2026-07-13 18:02:44 +08:00
parent 4826e3301c
commit 3a2f90c567
3 changed files with 48 additions and 4 deletions
+4 -4
View File
@@ -24,11 +24,11 @@ SUBTITLE_EPISODE_ALL_RE = re.compile(
r"([0-9一二三四五六七八九十百零]+)\s*集\s*全|[全共]\s*([0-9一二三四五六七八九十百零]+)\s*[集话話期幕]", r"([0-9一二三四五六七八九十百零]+)\s*集\s*全|[全共]\s*([0-9一二三四五六七八九十百零]+)\s*[集话話期幕]",
re.IGNORECASE, re.IGNORECASE,
) )
# 01-26Fin / [01-38 END] / 01-24完结 等"数字范围+完结标记"格式,完结标记必须 # 结尾分支显式区分有无右方括号,避免可选括号回溯后绕过数字后缀边界
# 存在以避免年份范围(如 2019-2020)误识别为集数;Fin/End 后不能紧跟字母数字,
# 避免 Final/Ending 等单词前缀误匹配
SUBTITLE_EPISODE_RANGE_FIN_RE = re.compile( SUBTITLE_EPISODE_RANGE_FIN_RE = re.compile(
r"(?<!\d)\[?\s*(\d{1,4})\s*-\s*(\d{1,4})\s*(?:(?:Fin|End)(?![a-z0-9])|完结(?![\u4e00-\u9fff]))\s*\]?(?!\d)", r"(?<!\d)\[?\s*(\d{1,4})\s*-\s*(\d{1,4})\s*"
r"(?:(?:Fin|End)(?![a-z0-9])|完结(?![\u4e00-\u9fff]))"
r"(?:\s*\](?!\d)|(?!\s*(?:\]\d|\d))\s*)",
re.IGNORECASE, re.IGNORECASE,
) )
VIDEO_BIT_RE = re.compile( VIDEO_BIT_RE = re.compile(
+27
View File
@@ -184,6 +184,20 @@ def test_python_subtitle_episode_range_fin_with_chinese_season():
assert meta.total_episode == 26 assert meta.total_episode == 26
def test_subtitle_episode_range_fin_with_default_parser():
"""默认解析路径应识别副标题中 [01-26Fin] 格式的集数范围(#6103)。"""
meta = MetaInfo(
title="JoJos Bizarre Adventure S01 2012 1080i BluRay x264 FLAC 2.0-AnimeF@ADE",
subtitle="JOJO的奇妙冒险 第一季 / JoJo's Bizarre Adventure [01-26Fin] [简繁字幕]",
)
assert meta.type == MediaType.TV
assert meta.begin_season == 1
assert meta.begin_episode == 1
assert meta.end_episode == 26
assert meta.total_episode == 26
def test_python_subtitle_episode_range_fin_without_chinese_marker(): def test_python_subtitle_episode_range_fin_without_chinese_marker():
"""副标题无中文季集标记时也应识别 [01-38Fin] 集数范围。""" """副标题无中文季集标记时也应识别 [01-38Fin] 集数范围。"""
with patch("app.core.metainfo.rust_accel.parse_metainfo", return_value=None): with patch("app.core.metainfo.rust_accel.parse_metainfo", return_value=None):
@@ -227,6 +241,19 @@ def test_python_subtitle_year_range_not_treated_as_episodes():
assert meta.total_episode == 0 assert meta.total_episode == 0
def test_python_subtitle_episode_range_fin_rejects_numeric_suffix():
"""Python 兜底解析不得把带数字后缀的完结范围截断识别为集数。"""
for subtitle in ("Some Show [01-26Fin]2", "Some Show 01-26Fin 2"):
with patch("app.core.metainfo.rust_accel.parse_metainfo", return_value=None):
meta = MetaInfo(
title="Some Show S01 2022 1080p WEB-DL H264-GRP",
subtitle=subtitle,
)
assert meta.begin_episode is None
assert meta.total_episode == 0
def test_custom_words_replace_then_episode_offset(): def test_custom_words_replace_then_episode_offset():
"""测试复杂识别词仍按先替换、后集数偏移的顺序处理。""" """测试复杂识别词仍按先替换、后集数偏移的顺序处理。"""
custom_words = ["旧名 => 新名 && 第 <> 集 >> EP+1"] custom_words = ["旧名 => 新名 && 第 <> 集 >> EP+1"]
+17
View File
@@ -257,6 +257,23 @@ def test_rust_metainfo_parser_handles_episode_group():
assert result["begin_season"] == 1 assert result["begin_season"] == 1
def test_rust_metainfo_parser_handles_subtitle_episode_range_fin():
"""
Rust MetaInfo 入口应识别副标题中的数字范围完结标记。
"""
result = rust_accel.parse_metainfo(
"JoJos Bizarre Adventure S01 2012 1080i BluRay x264 FLAC 2.0-AnimeF@ADE",
subtitle="JOJO的奇妙冒险 第一季 / JoJo's Bizarre Adventure [01-26Fin] [简繁字幕]",
options=_metainfo_options(),
)
assert result["type"] == MediaType.TV.value
assert result["begin_season"] == 1
assert result["begin_episode"] == 1
assert result["end_episode"] == 26
assert result["total_episode"] == 26
def test_rust_metainfo_path_parser_merges_parent_title(): def test_rust_metainfo_path_parser_merges_parent_title():
""" """
Rust MetaInfoPath 入口应在 Rust 内完成父目录标题合并。 Rust MetaInfoPath 入口应在 Rust 内完成父目录标题合并。