fix(titleMatches): 查询词含季号时追加去季变体,防止无季标题被误过滤 (#359)

查询词含季号(如"间谍过家家 第一季")时,源返回的标题
可能不含季标记(如"间谍过家家(N/A)【动漫】"),策略2
包含匹配因"第一季"三字不存在而失败,退至策略3相似度又
因季后缀降低匹配率,最终被误过滤。

将去季后的干净查询词(使用 merge-util INFO_STRONG 标准
季正则)加入候选池,季校验前提作为闸门防止跨季误匹配。
This commit is contained in:
Elegy233 authored and GitHub committed 2026-07-04 22:06:00 +08:00
1 parent 8eccc3dfbc
commit 0bcb0aace6
1 file changed
+15 -4
+15 -4
View File
@@ -278,11 +278,19 @@ export function titleMatches(title, query, parsedSeason = null) {
.map(kw => normalizeSpaces(kw).toLowerCase()).filter(Boolean);
} catch (e) {}
// 策略2:包含匹配优先 (性能最优且准确,只要完整包含任意变种即匹配)
if (qList.some(kw => t.includes(kw))) return true;
// 季度特征校验 (针对策略3的宽松相似度,防止字符集混淆导致季度错乱)
// 季度特征提取:提前提取季数以支撑策略2的去季包含匹配
const querySeason = parsedSeason !== null ? parsedSeason : getExplicitSeasonNumber(query);
// 查询词含季号时,将去季后的干净查询词加入候选池
// 避免如"间谍过家家 第一季"因"第一季"三字不存在于源标题而导致包含匹配失败
if (querySeason !== null && parsedSeason === null) {
const seasonStripped = query.replace(/(?:season|s|第)\s*[0-9一二三四五六七八九十]+\s*(?:季|期|部(?!分))?/gi, '').trim();
if (seasonStripped && seasonStripped !== query) {
qList = [...new Set([...qList, normalizeSpaces(seasonStripped).toLowerCase()])];
}
}
// 季度特征校验:先于包含匹配执行,确保错误季度的标题不会因干净查询词误通过
if (querySeason !== null) {
const titleSeason = getExplicitSeasonNumber(title);
@@ -295,6 +303,9 @@ export function titleMatches(title, query, parsedSeason = null) {
}
}
// 策略2:包含匹配优先 (性能最优且准确,只要完整包含任意变种即匹配)
if (qList.some(kw => t.includes(kw))) return true;
// 策略3:相似度匹配 (阈值0.8)
return qList.some(kw => {
// 长度差异过大,或纯英文/数字时,禁止使用相似度计算策略