Python中使用str()函数的errors='replace'时能否指定自定义替换字符?
Python中使用str()函数的errors='replace'时能否指定自定义替换字符?
很遗憾,直接用str(bytes_obj, encoding='utf-8', errors='replace')这种方式没法自定义替换字符——默认就是那个�符号。不过结合你处理GPS数据的实际场景,有几种更实用的替代方案,既能满足替换需求,还能解决你遇到的初始垃圾字符问题:
1. 处理编码错误的无效字节:替换为空或自定义字符
如果你的目标是处理无效UTF-8字节(不是那些初始的垃圾有效字符),可以用这两种方法:
方法一:用codecs模块自定义错误处理
这是最灵活的方式,能完全控制替换逻辑:
import codecs def custom_error_handler(error): # 返回('', error.start + 1) 表示跳过错误字节(替换为空) # 要是想替换成其他字符,比如'_',就改成返回('_', error.start + 1) return ('', error.start + 1) # 注册自定义错误处理规则 codecs.register_error('custom_ignore', custom_error_handler) # 读取并处理串行数据 raw_bytes = self.ser.readline().strip() clean_line = raw_bytes.decode('utf-8', errors='custom_ignore')
方法二:直接用errors='ignore'忽略无效字节
其实你之前用的errors='ignore'本质就是把无效字节替换为空,完全符合你“替换成nothing”的需求~不过要注意,它只处理编码错误的字节,对那些初始的垃圾有效字符(比如你例子里的JSSHubbbbrb95))没用,因为这些本身是合法的UTF-8字符。
2. 处理GPS初始的垃圾有效字符:直接过滤无效行
你提到的那些开头乱码,是通信建立时的正常现象,它们不是编码错误,而是完整的有效字符。这种情况最好的处理方式不是替换,而是直接跳过这些无效行,直到找到标准的NMEA句子:
def read_valid_gps_line(ser): while True: raw_bytes = ser.readline().strip() # 先处理编码错误,再判断是否是有效NMEA行 raw_line = str(raw_bytes, encoding='utf-8', errors='ignore') if raw_line.startswith('$GP'): return raw_line # 否则继续循环读取,直到拿到有效行
这样就能自动跳过那些初始垃圾,直接拿到你需要的$GP开头的有效数据,比替换字符要更精准。
总结一下
- 如果是编码错误的无效字节:用
errors='ignore'(替换为空)或者codecs自定义处理(替换成任意字符); - 如果是通信初始的垃圾有效字符:直接过滤掉不以
$GP开头的行,只保留有效NMEA句子。
备注:内容来源于stack exchange,提问作者Jim JR Harris
相关产品推荐
相关产品推荐

