Python3.6中读取Excel数据时使用re.sub()无法替换特殊字符是什么原因?
Python 特殊字符替换失效问题排查
问题背景
我正在做一个需要用Python读取Excel表格数据的项目,过程中发现使用re.sub()时,原始字符串中的指定字符没有被替换,但改用string.replace()就可以正常替换,调整为translate批量替换方案后仍然无法移除非法字符,需要定位问题原因。
环境信息
- Python版本:3.6
- 操作系统:Windows 10
- 依赖库:openpyxl
相关代码
初始实现
string = re.sub(u'([\u2000-\u206f])', " ", string) string = re.sub(u'(\u00a0)', " ", string) string = string.replace("‰", " ") #\u0089 string = string.replace("¤", " ") #\u00a4
优化后实现
replacementDict = {} replacementDict.update(dict.fromkeys(map(chr, range(0x2000, 0x206f)), " ")) replacementDict['\u00a0'] = " " replacementDict['\u0089'] = " " replacementDict['\u00a4'] = " " string = string.translate(replacementDict)
复现步骤
直接运行原脚本(无需传入参数),即可观察到匹配失败的行均为包含非法字符的行。
问题根因
- 字符码点匹配错误:你注释中标注
‰对应的码点是\u0089,但实际可见字符‰的Unicode码点是\u2030,\u0089是不可见的C1控制字符,二者完全不同,这是replace直接写字符合效、转义码匹配失效的核心原因。 - 正则/映射表范围错误:你写的
range(0x2000, 0x206f)是左闭右开区间,实际只能覆盖到0x206e,会漏掉0x206f的字符;同时映射表中填入的是错误的\u0089,自然无法匹配到真实的‰字符。 - 编码处理偏差:openpyxl读取Excel文件时如果没有做编码兼容处理,部分特殊字符会被转义为其他编码格式再解码,也会导致你预设的Unicode码点和实际读取到的字符码点不匹配。
解决方案
第一步:先确认实际字符码点
先打印异常字符串中每个字符的实际码点,避免凭记忆写转义码出错:
# 传入匹配失败的字符串,输出所有字符的实际码点 for char in bad_string: print(f"字符:{repr(char)}, 十六进制码点:{ord(char):#06x}")
方案A:修正正则匹配规则
确认所有需要替换的字符码点后,统一写在正则字符集里批量替换:
import re # 示例包含:2000-206f全区间、不间断空格\u00a0、货币符号¤\u00a4、千分号‰\u2030 replace_pattern = re.compile(r'[\u2000-\u206f\u00a0\u00a4\u2030]') string = replace_pattern.sub(' ', string)
方案B:修正translate映射表
replacement_dict = {} # 区间右边界设为0x2070,确保覆盖到0x206f replacement_dict.update(dict.fromkeys(map(chr, range(0x2000, 0x2070)), " ")) replacement_dict['\u00a0'] = " " replacement_dict['\u2030'] = " " # 修正千分号‰的正确码点 replacement_dict['\u00a4'] = " " string = string.translate(replacement_dict)
内容的提问来源于stack exchange,提问作者Luis
相关产品推荐
相关产品推荐

