如何用Python处理PDF提取文本的换行/对齐问题并保留段落结构
解决PDF提取文本的智能换行合并问题(适配Spacy后续处理)
我刚好处理过类似的PDF文本提取后换行乱序的问题,给你一套实用的Python解决方案——既能严格保留原文档的段落间距结构,又能智能合并句子内的不必要换行,完美适配后续用Spacy做拼写检查、多语言文本处理的需求:
核心思路
从PDF提取的文本里,句子内的换行是原文档两端对齐排版导致的(一行放不下完整的单词/分句),而段落分隔则来自原文档的双倍行距(表现为文本中的空行)。我们的目标就是:只合并句子内部的换行,同时完整保留段落间的空行结构。
基础实现代码
用正则表达式精准区分段落和行内换行,优先处理非句子结尾的换行:
import re def smart_merge_line_breaks(raw_text): # 第一步:统一所有换行符为\n,避免CR/LF混合的混乱 normalized_text = raw_text.replace('\r\n', '\n').replace('\r', '\n') # 第二步:拆分段落——用两个及以上换行符作为段落分隔标志 paragraphs = re.split(r'\n{2,}', normalized_text) # 第三步:逐个清理段落内的无效换行 cleaned_paragraphs = [] for para in paragraphs: # 跳过空段落 if not para.strip(): continue # 合并段落内的非句子结尾换行: # 负向断言规则:换行前不是中英文句子结束标点/闭合符号,且换行后不是另一个换行(确保是段落内的行) merged_para = re.sub( r'(?<!\.|\?|\!|\。|\!|\?|\)|\]|\")\n(?!\n)', ' ', para.strip() ) cleaned_paragraphs.append(merged_para) # 第四步:用空行连接处理后的段落,还原原有的段落结构 return '\n\n'.join(cleaned_paragraphs)
进阶优化:处理连字符拆分的英文单词
如果原PDF里有英文单词因换行被拆成带连字符的两行(比如exam-\nple),可以在基础代码里加一步针对性处理:
def smart_merge_line_breaks_with_hyphen(raw_text): normalized_text = raw_text.replace('\r\n', '\n').replace('\r', '\n') paragraphs = re.split(r'\n{2,}', normalized_text) cleaned_paragraphs = [] for para in paragraphs: if not para.strip(): continue # 先处理连字符换行:去掉连字符和换行,合并完整单词 para = re.sub(r'-\n', '', para) # 再处理普通的句子内换行 merged_para = re.sub( r'(?<!\.|\?|\!|\。|\!|\?|\)|\]|\")\n(?!\n)', ' ', para.strip() ) cleaned_paragraphs.append(merged_para) return '\n\n'.join(cleaned_paragraphs)
适配后续Spacy处理的优势
- 拼写检查更准确:不会把被换行拆分的单词(比如
exa\nmple)误判为拼写错误; - 非英文文本检测更可靠:中文等无空格语言的文本不会被换行分割成零散片段,Spacy的多语言模型能更精准地识别和处理;
- 分词/句法分析更顺畅:连贯的文本能让Spacy正确识别句子边界和语法结构,避免因换行导致的模型误判。
注意事项
- 如果原PDF的段落不是用空行分隔,而是用缩进,你需要调整段落拆分的正则规则(比如用
r'(?<=\n)\s{4,}'匹配缩进作为段落分隔); - 可以根据实际PDF的标点风格,补充更多句子结尾符号到正则的断言规则里(比如中文的
;、英文的:等)。
内容的提问来源于stack exchange,提问作者mobcdi




