diff --git a/app/core/meta/metamusic.py b/app/core/meta/metamusic.py index f143ca586..e9a5a63d5 100644 --- a/app/core/meta/metamusic.py +++ b/app/core/meta/metamusic.py @@ -571,8 +571,11 @@ class MetaMusic(MetaBase): alias_match.group("alias").casefold(), "Various Artists")] self._finalize_title(self._clean_tail(alias_match.group("title"))) else: - # CJK 标题常见「专辑名-歌手」无空格连字符写法,主拆分未命中时兑底反向拆分 + # CJK 标题常见「专辑名-歌手」无空格连字符写法,主拆分未命中时兜底反向拆分 artists, title = self._split_cjk_hyphen(cleaned) + if not artists: + # 拉丁「艺术家-专辑」无空格连字符写法(Gene Clark-White Light) + artists, title = self._split_latin_hyphen(cleaned) if artists: self.artists = artists self._finalize_title(self._clean_tail(title)) @@ -784,6 +787,26 @@ class MetaMusic(MetaBase): return [artist], head return None, text + @classmethod + def _split_latin_hyphen(cls, value: str) -> tuple[Optional[list[str]], str]: + """拉丁「艺术家-专辑」无空格连字符命名拆分(Gene Clark-White Light)。 + + 首个连字符左侧为艺术家;两侧均需含空格(至少两个词)才采信: + 左侧保护 Jay-Z 类连字符艺术家名,右侧排除 -ProfessorP 类发布组标签; + 艺术家身份由候选比对验证。 + """ + text = str(value or "").strip() + if cls._contains_cjk(text): + return None, text + head, sep, tail = text.partition("-") + if not sep: + return None, text + head = head.strip(" \t-–—−-") + tail = tail.strip(" \t-–—−-") + if head and tail and " " in head and " " in tail: + return cls._split_artists(head), tail + return None, text + @staticmethod def _compact_text(value: Any) -> str: """移除大小写、空白与标点,生成比对使用的紧凑文本。""" diff --git a/tests/test_metamusic.py b/tests/test_metamusic.py index 49b7bb7e3..b55d10a22 100644 --- a/tests/test_metamusic.py +++ b/tests/test_metamusic.py @@ -171,6 +171,17 @@ def test_apply_title_strips_video_tokens(): assert meta.year == 2018 +def test_apply_title_splits_latin_hyphen_artist_album(): + """拉丁「艺术家-专辑」无空格连字符命名应拆分,单侧单词不采信。""" + meta = parse_title("Gene Clark-White Light 1971 - FLAC 16bit 44 1khz") + + assert meta.artists == ["Gene Clark"] + assert meta.title == "White Light" + assert meta.year == 1971 + # 左侧单词(Heize-Undo)与右侧发布组标签不触发拆分 + assert parse_title("Heize-Undo.2022.FLAC").artists == [] + + def test_apply_title_splits_various_artists_prefix(): """场景命名的 Various Artists-Title 无空格连字符前缀应拆分为合辑署名。""" meta = parse_title("Various.Artists-Reply.1988.OST")