Python正则分词后重组为18-30词定长句段的实现方法
无常规句末标点长段落的切分拼接实现
核心优化点
- 修正原有分割正则,补充冒号
:作为分割字符,解决原逻辑下末尾段长达76词的问题,正则使用原始字符串避免转义错误:
regex_special_chars = r'([″;*"(§=!‡…†\?\]‘)¿♥[:]+)'
- 拼接逻辑严格遵循18-30词的目标区间要求,对单片段超长、末尾剩余片段这类受分词边界限制的内容做容错,不强制卡长度。
实现逻辑
- 调用
re.split()按上述正则切分长段落,过滤掉切分产生的空字符串、纯空白片段 - 维护临时拼接缓存,逐一遍历切分后的片段,实时计算缓存+当前片段拼接后的总词数(按空格拆分计数即可)
- 拼接后词数不足18时,持续将片段加入缓存累加
- 拼接后词数落在18-30区间时,将拼接完成的句段存入最终结果列表,清空缓存
- 拼接后词数超过30时:如果缓存为空说明单个片段本身超长,属于特殊边界片段直接存入结果;如果缓存不为空,先将现有缓存内容作为完整句段存入,再把当前片段放入新缓存
- 所有片段遍历完成后,缓存中剩余的内容无论长度多少,直接存入结果列表(对应末尾不受长度约束的特殊段)
完整可运行代码
import re from typing import List def segment_long_paragraph(long_text: str) -> List[str]: # 配置参数 MIN_WORDS = 18 MAX_WORDS = 30 # 补充冒号的分割正则,用原始字符串避免转义问题 split_pattern = r'([″;*"(§=!‡…†\?\]‘)¿♥[:]+)' # 切分并预处理片段 raw_fragments = [ frag.strip() for frag in re.split(split_pattern, long_text) if frag.strip() ] result = [] temp_cache = [] cache_word_cnt = 0 for frag in raw_fragments: frag_word_cnt = len(frag.split()) total_after_merge = cache_word_cnt + frag_word_cnt if total_after_merge < MIN_WORDS: temp_cache.append(frag) cache_word_cnt = total_after_merge elif MIN_WORDS <= total_after_merge <= MAX_WORDS: temp_cache.append(frag) result.append(' '.join(temp_cache)) temp_cache.clear() cache_word_cnt = 0 else: if not temp_cache: # 单片段本身超长,属于边界特殊情况直接存入 result.append(frag) cache_word_cnt = 0 else: # 先存满长度的缓存内容,再把当前片段放入新缓存 result.append(' '.join(temp_cache)) temp_cache = [frag] cache_word_cnt = frag_word_cnt # 处理末尾剩余片段,不限制长度 if temp_cache: result.append(' '.join(temp_cache)) return result
效果说明
- 加入冒号分割后,原逻辑中76词的过长末尾段会被切分为更短的子片段,绝大多数句段都能稳定落在18-30词的目标区间
- 不需要依赖NLTK预训练分句模型,完全适配仅末尾带句号、缺少常规句间停顿标点的长文本场景
- 特殊片段容错逻辑不会强行拆分超长边界内容,避免出现语义断裂的问题
内容的提问来源于stack exchange,提问作者Akbar Hussein
相关产品推荐
相关产品推荐

