Python处理Word 97-2003文档编码问题:非打印字符干扰正则提取
解决Word 97-2003文档提取信息时的非打印字符与重复输出问题
核心问题根源
Word 97-2003(.doc)是二进制复合文档格式,并非纯文本文件。直接用文本编码读取原始字节内容,会把文档的格式控制元数据、二进制结构信息当成文本解析——这就是你遇到大量非打印字符和重复输出的根本原因:你处理的不是纯净的文档内容,而是夹杂了各种格式标记的二进制数据。
正确处理步骤
1. 先提取纯净文本,再处理非打印字符
不要直接读取.doc文件的原始内容,用专门工具提取其中的纯文本:
方案一:Windows环境用pywin32调用Word COM接口
这是最可靠的方式,直接利用Word本身解析文档:
import win32com.client import os def extract_doc_text(doc_path): word = win32com.client.Dispatch("Word.Application") word.Visible = False doc = word.Documents.Open(os.path.abspath(doc_path)) text = doc.Content.Text doc.Close() word.Quit() return text
提取出的text已经是纯净的可阅读文本,不会包含文档的二进制结构信息。
方案二:跨平台用antiword或textract
- antiword:专门提取.doc文件文本的开源工具,安装后用Python调用:
import subprocess def extract_doc_text(doc_path): result = subprocess.run(["antiword", doc_path], capture_output=True, text=True) return result.stdout - textract:封装了多种文档提取工具的Python库,安装后直接调用:
import textract text = textract.process(doc_path, method='antiword').decode('utf-8')
2. 清理残留的非打印字符
提取到纯净文本后,再处理可能残留的控制字符(如软回车、分页符等):
import re import string def clean_text(text): # 保留常用可打印字符(包括中文)+ 必要的换行、制表符 printable = string.printable + ''.join([chr(i) for i in range(0x4E00, 0x9FA6)]) # 加入中文Unicode范围 # 替换所有不在printable里的字符为空 cleaned = re.sub(f'[^{re.escape(printable)}]', '', text) # 去除多余的重复换行/空格 cleaned = re.sub(r'\s+', ' ', cleaned).strip() return cleaned
如果不需要保留换行,可将\s+替换为 ,统一转为单个空格。
3. 解决重复输出问题
重复打印的原因是你之前直接读取二进制文档时,把文档中重复存储的结构(比如Word的冗余数据块)当成了文本内容。用上面的方法提取纯净文本后,重复内容会自然消失。若提取后仍有重复,检查文档本身是否存在重复内容,或用正则去重:
# 去除连续重复的段落(假设段落以换行分隔) def remove_duplicate_paragraphs(text): paragraphs = text.split('\n') seen = set() unique_paragraphs = [] for para in paragraphs: stripped = para.strip() if stripped not in seen and stripped: seen.add(stripped) unique_paragraphs.append(para) return '\n'.join(unique_paragraphs)
总结
- 放弃直接读取.doc原始文件的做法,用专业工具提取纯文本;
- 提取后再做非打印字符清理,此时正则才能正常工作;
- 重复输出问题会随着正确提取文本而解决,若仍有重复则针对性去重。
内容的提问来源于stack exchange,提问作者aivarsstrauss
相关产品推荐
相关产品推荐

