From 6c236dcb71adfde97c2190ab83ed94fb5879ddcd Mon Sep 17 00:00:00 2001 From: Elegy233 <82034747+wan0ge@users.noreply.github.com> Date: Sat, 4 Jul 2026 22:03:07 +0800 Subject: [PATCH] =?UTF-8?q?fix(merge):=20=E4=B8=AD=E6=96=87=E6=95=B0?= =?UTF-8?q?=E5=AD=97=E5=AD=A3=E5=8F=B7=E6=AD=A3=E5=88=99=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E8=B6=85=E8=BF=87=E5=8D=81=E7=9A=84=E6=95=B0=E5=AD=97=20(#357)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RegexStore.Season.CN 字符类缺少 + 量词,导致 第十三季 等超过十的中文季号只匹配首字 十,与 第十五季 等一同 被误规范为 第10季,引发错误合并。 正则追加 + 量词支持多字符中文数字, cnNums 查表替换为 convertChineseNumber 处理任意长度。 --- danmu_api/utils/merge-util.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/danmu_api/utils/merge-util.js b/danmu_api/utils/merge-util.js index 105916e..a79467b 100644 --- a/danmu_api/utils/merge-util.js +++ b/danmu_api/utils/merge-util.js @@ -2,7 +2,7 @@ import { globals } from '../configs/globals.js'; import { log as baseLog } from './log-util.js'; import { addAnime } from './cache-util.js'; import { simplized } from '../utils/zh-util.js'; -import { normalizeSpaces } from '../utils/common-util.js'; +import { normalizeSpaces, convertChineseNumber } from '../utils/common-util.js'; // ============================================================================== // 源合并处理工具 (merge-util.js) @@ -139,7 +139,7 @@ const RegexStore = { PART_NORM_2: /(?:Part|P)[\s.]*(\d+)/gi, FINAL: /(?:The\s+)?Final\s+Season/gi, NORM: /(?:Season|S)\s*(\d+)/gi, - CN: /第\s*([一二三四五六七八九十])\s*季/g, + CN: /第\s*([一二三四五六七八九十]+)\s*季/g, ROMAN: /(\s|^)(IV|III|II|I)(\s|$)/g, INFO_STRONG: /(?:season|s|第)\s*[0-9一二三四五六七八九十]+\s*(?:季|期|部(?!分))?/gi, PART_INFO_STRONG: /(?:part|p|第)\s*\d+\s*(?:部分)?/gi, @@ -377,8 +377,7 @@ function cleanText(text) { clean = clean.replace(RegexStore.Season.FINAL, '最终季'); clean = clean.replace(RegexStore.Season.NORM, '第$1季'); // 中文数字季度转阿拉伯数字 - const cnNums = { '一':'1','二':'2','三':'3','四':'4','五':'5','六':'6','七':'7','八':'8','九':'9','十':'10' }; - clean = clean.replace(RegexStore.Season.CN, (m, num) => `第${cnNums[num]}季`); + clean = clean.replace(RegexStore.Season.CN, (m, num) => `第${convertChineseNumber(num)}季`); // 罗马数字季度转阿拉伯数字 clean = clean.replace(RegexStore.Season.ROMAN, (match, p1, roman, p2) => { const rMap = { 'I':'1','II':'2','III':'3','IV':'4' }; @@ -1142,7 +1141,7 @@ function identifyRedundantTitle(links, seriesTitle, sourceName) { try { let regex = _redundantTitleRegexCache.get(sourceName); if (!regex) { - const escapedSource = sourceName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + const escapedSource = escapeRegExp(sourceName); regex = new RegExp(`(\\[|【|\\s)?${escapedSource}(\\]|】|\\s)?`, 'gi'); _redundantTitleRegexCache.set(sourceName, regex); } @@ -2113,7 +2112,6 @@ function detectCollectionCandidates(curAnimes) { const collectionIds = new Set(); if (!curAnimes || curAnimes.length === 0) return collectionIds; - const cnNums = {'一':'1','二':'2','三':'3','四':'4','五':'5','六':'6','七':'7','八':'8','九':'9','十':'10'}; const groups = new Map(); curAnimes.forEach(anime => { @@ -2131,7 +2129,7 @@ function detectCollectionCandidates(curAnimes) { protectedTitle = protectedTitle.replace(startBracketMatch[0], content + ' '); } } - protectedTitle = protectedTitle.replace(/第([一二三四五六七八九十])季/g, (m, num) => `第${cnNums[num]}季`); + protectedTitle = protectedTitle.replace(/第([一二三四五六七八九十]+)季/g, (m, num) => `第${convertChineseNumber(num)}季`); // 去除所有元数据,只保留核心标题用作分组 key let clean = protectedTitle