@minto-ai/text-stream-slicer
Version:
使用 `pnpm` 进行安装
148 lines (147 loc) • 5.22 kB
JavaScript
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
};