"""长文本分段工具 — P1 长文本分段合成。 将超过阈值的文本按句子边界分段,供 CosyVoice 并发合成后合并。 """ from __future__ import annotations # 中文句子结束符(含全角/半角) _SENTENCE_ENDS = frozenset("。!?;\n.!?;") def split_text(text: str, max_chars: int = 500) -> list[str]: """将文本分段,每段不超过 max_chars 个字符。 优先在句子边界(句号、问号、感叹号、换行符)处分段。 若单个句子超过 max_chars,则在逗号等次级标点处拆分。 若仍超长,则硬切。 Args: text: 待分段文本 max_chars: 每段最大字符数 Returns: 分段列表,每段 ≤ max_chars。文本为空时返回空列表。 """ text = text.strip() if not text: return [] if len(text) <= max_chars: return [text] segments: list[str] = [] current = "" for char in text: current += char if char in _SENTENCE_ENDS and len(current) >= 50: # 句子边界且长度合理,切段 segments.append(current.strip()) current = "" elif len(current) >= max_chars: # 达到上限,强制切段 segments.append(current.strip()) current = "" if current.strip(): segments.append(current.strip()) # 合并过短的段(< 50 字符且不是最后一段),减少 API 调用次数 merged: list[str] = [] buffer = "" for seg in segments: if buffer: combined = buffer + seg if len(combined) <= max_chars: buffer = combined continue merged.append(buffer) buffer = "" if len(seg) < 50: buffer = seg else: merged.append(seg) if buffer: if merged and len(merged[-1]) + len(buffer) <= max_chars: merged[-1] = merged[-1] + buffer else: merged.append(buffer) return [s for s in merged if s]