export type MaterialPlaceholder = { token: string; type: "image" | "video" | "audio"; index: number; }; const materialTokenPattern = /@(参考视频|图片|图|视频|音频)(\d+)/g; export function extractMaterialPlaceholders(prompt: string): MaterialPlaceholder[] { const placeholders: MaterialPlaceholder[] = []; const seen = new Set(); for (const match of prompt.matchAll(materialTokenPattern)) { const kind = match[1]; const index = Number(match[2]); if (!Number.isInteger(index) || index < 1) continue; const type = typeForKind(kind); const token = labelForPlaceholder(type, index); if (seen.has(token)) continue; seen.add(token); placeholders.push({ token, type, index }); } return placeholders; } function typeForKind(kind: string): MaterialPlaceholder["type"] { if (kind === "视频" || kind === "参考视频") return "video"; if (kind === "音频") return "audio"; return "image"; } function labelForPlaceholder(type: MaterialPlaceholder["type"], index: number) { if (type === "video") return `@视频${index}`; if (type === "audio") return `@音频${index}`; return `@图片${index}`; }