72 lines
2.8 KiB
TypeScript
72 lines
2.8 KiB
TypeScript
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<string, number> = {
|
|
一: 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<number>();
|
|
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);
|
|
}
|