function chineseNumberToInt(value: string): number | null { const normalized = value.trim(); if (!normalized) return null; if (/^\d+$/.test(normalized)) return Number.parseInt(normalized, 10); const map: Record = { 一: 1, 二: 2, 两: 2, 三: 3, 四: 4, 五: 5, 六: 6, 七: 7, 八: 8, 九: 9, 十: 10, }; if (normalized === "十") return 10; if (normalized.length === 1) return map[normalized] ?? null; if (normalized.startsWith("十")) { return 10 + (map[normalized.slice(1)] ?? 0); } if (normalized.endsWith("十")) { return (map[normalized.slice(0, 1)] ?? 0) * 10; } if (normalized.includes("十")) { const [head, tail] = normalized.split("十"); return (map[head] ?? 0) * 10 + (map[tail] ?? 0); } return null; } export function collectOrdinalImageIndexes(text: string): number[] { const indexes = new Set(); const normalizedText = String(text || ""); const chineseOrdinalPattern = /第\s*([一二三四五六七八九十两\d]+)\s*(?:张|个|幅)?\s*(?:图|图片|照片)?/gi; const numberedImagePattern = /(?:图|图片|照片|image|photo|reference)\s*([1-9]\d*)\b/gi; const compactChineseImagePattern = /(?:图片|照片|图)\s*([一二两三四五六七八九十])(?![一二两三四五六七八九十\d维])/g; const englishOrdinals: Array<{ index: number; pattern: RegExp }> = [ { index: 0, pattern: /\b(?:first|1st)\s+(?:image|photo|reference)\b/i }, { index: 1, pattern: /\b(?:second|2nd)\s+(?:image|photo|reference)\b/i }, { index: 2, pattern: /\b(?:third|3rd)\s+(?:image|photo|reference)\b/i }, { index: 3, pattern: /\b(?:fourth|4th)\s+(?:image|photo|reference)\b/i }, { index: 4, pattern: /\b(?:fifth|5th)\s+(?:image|photo|reference)\b/i }, { index: 5, pattern: /\b(?:sixth|6th)\s+(?:image|photo|reference)\b/i }, { index: 6, pattern: /\b(?:seventh|7th)\s+(?:image|photo|reference)\b/i }, { index: 7, pattern: /\b(?:eighth|8th)\s+(?:image|photo|reference)\b/i }, ]; for (const match of normalizedText.matchAll(chineseOrdinalPattern)) { const numeric = chineseNumberToInt(match[1] || ""); if (numeric && numeric > 0) indexes.add(numeric - 1); } for (const match of normalizedText.matchAll(numberedImagePattern)) { const numeric = Number.parseInt(match[1] || "", 10); if (Number.isFinite(numeric) && numeric > 0) indexes.add(numeric - 1); } for (const match of normalizedText.matchAll(compactChineseImagePattern)) { const numeric = chineseNumberToInt(match[1] || ""); if (numeric && numeric > 0) indexes.add(numeric - 1); } for (const item of englishOrdinals) { if (item.pattern.test(normalizedText)) indexes.add(item.index); } return Array.from(indexes).sort((left, right) => left - right); }