UNPKG

@minto-ai/text-stream-slicer

Version:

使用 `pnpm` 进行安装

148 lines (147 loc) 5.22 kB
var l = Object.defineProperty; var r = (i, e, t) => e in i ? l(i, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[e] = t; var h = (i, e, t) => r(i, typeof e != "symbol" ? e + "" : e, t); var N = /* @__PURE__ */ ((i) => (i.SPACE_CHAR = "spaceChar", i.CHINESE_CHAR = "chineseChar", i.CHINESE_PUNCTUATION = "chinesePunctuation", i.ENGLISH_WORD = "englishWord", i.ENGLISH_PUNCTUATION = "englishPunctuation", i.UNKNOWN_CHAR = "unknownChar", i))(N || {}); class R { constructor() { // 中文字符 h(this, "CHINESE_CHAR_REGEX", /[\u4E00-\u9FA5]/); // 中文标点符号 h(this, "CHINESE_PUNCTUATION_REGEX", /[。?!,;:“”‘’()—…、·]/); // // 中文段落结束符号(句末标点) h(this, "CHINESE_PARAGRAPH_END_REGEX", /[。?!;]/); // 英文单词起始字符 h(this, "ENGLISH_WORD_START_REGEX", /[a-z]/i); // 英文单词延续字符(含缩写和连字符) h(this, "ENGLISH_WORD_CONTINUE_REGEX", /[a-z'’-]/i); // 英文标点符号 h(this, "ENGLISH_PUNCTUATION_REGEX", /[.,!?;:'"()-]/); // 英文段落结束符号(句末标点) h(this, "ENGLISH_PARAGRAPH_END_REGEX", /[.!?;]/); // 空白字符(统一转为单个空格) h(this, "SPACE_CHAR_REGEX", /\s/); // 最小段落长度 h(this, "MIN_PARAGRAPH_LENGTH", 10); // 待处理的剩余文本标记 h(this, "pendingTokens", []); } /** * 将输入文本转换为标记流。 * @param text 原始文本内容。 * @returns 标记化后的文本标记数组。 */ tokenizeText(e) { const t = []; let s = 0; for (; s < e.length; ) { const n = e[s]; if (this.CHINESE_CHAR_REGEX.test(n)) t.push({ type: N.CHINESE_CHAR, value: n }); else if (this.ENGLISH_WORD_START_REGEX.test(n)) { const a = s; let E = s + 1; for (; E < e.length && this.ENGLISH_WORD_CONTINUE_REGEX.test(e[E]); ) E++; const _ = e.substring(a, E); t.push({ type: N.ENGLISH_WORD, value: _ }), s += _.length - 1; } else this.CHINESE_PUNCTUATION_REGEX.test(n) ? t.push({ type: N.CHINESE_PUNCTUATION, value: n }) : this.ENGLISH_PUNCTUATION_REGEX.test(n) ? t.push({ type: N.ENGLISH_PUNCTUATION, value: n }) : this.SPACE_CHAR_REGEX.test(n) ? t.push({ type: N.SPACE_CHAR, value: n }) : t.push({ type: N.UNKNOWN_CHAR, value: n }); s++; } return t; } /** * 文本净化预处理 - 去除无效字符和格式。 * @param text 原始文本。 * @returns 净化后的文本。 */ sanitizeText(e) { return e.replace(/\s+/g, " ").replace(/(\d+)\s+/g, "$1").replace(/\*+/g, "").replace(/[\u{1F000}-\u{1FAFF}]/gu, ""); } /** * 段落输出之前的整理逻辑。 * @param paragraphs 段落数组。 * @returns 整理后的段落数组。 */ sanitizeParagraphs(e) { return e.map((t) => t.trim()).filter((t) => t.length > 0); } /** * 判断标记是否为段落结束符号。 * @param token 文本标记。 * @returns 是否为段落结束符号。 */ isParagraphEndToken(e) { return this.CHINESE_PARAGRAPH_END_REGEX.test(e.value) || this.ENGLISH_PARAGRAPH_END_REGEX.test(e.value); } /** * 将标记数组转换回文本。 * @param tokens 文本标记数组。 * @returns 组合后的文本。 */ tokensToString(e) { return e.map((t) => t.value).join(""); } /** * 将标记流分割成多个段落。 * @param tokens 文本标记数组。 * @returns 分段后的标记数组集合。 */ splitToParagraphs(e) { const t = []; let s = []; for (const n of e) s.push(n), s.length >= this.MIN_PARAGRAPH_LENGTH && this.isParagraphEndToken(n) && (t.push(s), s = []); return s.length > 0 && t.push(s), t; } /** * 合并因小数点导致的错误分段。 * @param paragraphs 分段后的标记数组集合。 * @returns 合并后的标记数组集合。 */ mergeDecimalParagraphs(e) { return e.reduce((t, s) => { if (t.length === 0) t.push(s); else { const n = t[t.length - 1], a = this.tokensToString(n), E = this.tokensToString(s); /\d+\.$/.test(a) && /^\d+/.test(E) ? t[t.length - 1] = [...n, ...s] : t.push(s); } return t; }, []); } /** * 处理输入文本,返回分段后的文本数组。 * @param text 输入文本内容。 * @param includeRemaining 是否包含未完成的段落。 * @returns 分段后的文本数组。 */ processText(e, t = !1) { const s = this.tokenizeText(this.sanitizeText(e)), n = [...this.pendingTokens, ...s], a = this.mergeDecimalParagraphs(this.splitToParagraphs(n)); if (a.length > 0) { const E = a[a.length - 1], _ = E[E.length - 1]; t ? this.pendingTokens = [] : this.isParagraphEndToken(_) ? /\d+\.$/.test(this.tokensToString(E)) ? this.pendingTokens = a.pop() : this.pendingTokens = [] : this.pendingTokens = a.pop(); } return this.sanitizeParagraphs(a.map((E) => this.tokensToString(E))); } } export { R as default };