如何用正则表达式忽略PDF对比中带不同上标的相同词根差异
解决思路与方案
一、正则改进:提取词根后对比
你的原正则仅能匹配带特定上标的单词,无法完成“词根一致”的校验。核心思路是先从单词中剥离所有上标字符,得到纯净词根,再对比新旧文本中对应单词的词根是否相同。
步骤1:定义上标字符的正则范围
上标拉丁字母的Unicode覆盖以下区间(包含大小写):
- 大写上标A-Z:
\u1D2C-\u1D42 - 小写上标a-z:
\u1D43-\u1D63 - 补充上标字符:
\u1D66-\u1D7F、\u1DB8-\u1DBB
步骤2:编写工具函数提取词根
用正则替换掉所有上标字符,得到词根:
import re # 匹配所有上标拉丁字母的正则 superscript_re = re.compile(r'[\u1D2C-\u1D42\u1D43-\u1D63\u1D66-\u1D7F\u1DB8-\u1DBB]+') def extract_root(word): return superscript_re.sub('', word)
步骤3:对比词根判断差异
在差异检测时,对新旧文本中的每个单词对,分别提取词根,若词根相同则判定为无差异:
old_word = "wordᵃᵃᵃ" new_word = "wordᵇᵇᵇ" if extract_root(old_word) == extract_root(new_word): # 忽略该类仅上标不同的差异 pass else: # 标记为有效差异 pass
二、更优识别方法:结合PDF格式解析
如果PDF中的上标是通过**文本格式(基线偏移、字体缩小)**实现的,而非Unicode上标字符,纯正则会失效。此时可以直接解析PDF的文本样式,过滤掉上标格式的字符:
以pdfplumber库为例,它能获取每个字符的上标属性:
import pdfplumber from difflib import Differ def get_clean_text(pdf_path): clean_chars = [] with pdfplumber.open(pdf_path) as pdf: for page in pdf.pages: # 遍历每个字符,过滤掉上标格式的字符 for char in page.chars: if not char.get("superscript"): clean_chars.append(char["text"]) return "".join(clean_chars) # 处理新旧PDF文本,去除上标格式字符 old_clean = get_clean_text("old_version.pdf") new_clean = get_clean_text("new_version.pdf") # 对比处理后的文本,仅保留有效差异 differ = Differ() diff_result = list(differ.compare(old_clean.splitlines(), new_clean.splitlines()))
这种方法能从根源上排除格式导致的上标差异,比纯正则更准确。
内容的提问来源于stack exchange,提问作者Jim
相关产品推荐
相关产品推荐

