如何用Python为Tandy 1000 Deskmate旧DOC文件编写自定义UTF8解码器
Tandy 1000 Deskmate编码转UTF-8实现方案
你想要的给.decode()传入自定义映射规则的需求可以通过Python标准库codecs模块的自定义错误处理器实现,这是目前最优雅的实现方式:
方案1:自定义解码错误处理器(推荐)
该方案无需遍历全部字节,仅在解码遇到非ASCII字节时触发自定义映射逻辑,性能高且符合Python原生解码习惯。
import codecs # 先填入你手动确认的所有字节到Unicode字符的映射 BYTE_MAP = { 0xa9: '\u2014', # 示例:0xa9对应em dash # 继续添加其他映射规则,格式为 字节值: '目标Unicode字符' } def deskmate_error_handler(exc): if isinstance(exc, UnicodeDecodeError): err_byte = exc.object[exc.start] # 命中映射则返回对应字符,否则返回替换符� return (BYTE_MAP.get(err_byte, '\ufffd'), exc.start + 1) raise exc # 注册自定义错误处理器,注册后全局可用 codecs.register_error('deskmate_map', deskmate_error_handler) # 直接用原生decode方法解码,遇到非ASCII字节自动走自定义映射 # raw_bytes为你已加载的bytearray对象 decoded_text = raw_bytes.decode('ascii', errors='deskmate_map') # 保存为UTF-8格式文件 with open('转换后的文件.txt', 'w', encoding='utf-8') as f: f.write(decoded_text)
方案2:手动遍历字节(适合调试映射规则)
如果你的映射表还在调整,需要直观看到每个非ASCII字节的处理过程,可以用遍历方案:
# 同上面的BYTE_MAP映射表 BYTE_MAP = { 0xa9: '\u2014', # 其他映射 } decoded_chars = [] for byte in raw_bytes: if byte in BYTE_MAP: decoded_chars.append(BYTE_MAP[byte]) elif byte <= 127: # ASCII字符直接转换 decoded_chars.append(chr(byte)) else: # 未定义的非ASCII字节可先输出日志确认映射规则 print(f"发现未映射字节: 0x{byte:02x}") decoded_chars.append('\ufffd') decoded_text = ''.join(decoded_chars)
补充说明
你提到的chardetect检测结果没有参考价值,原因是文件中非ASCII字符占比极低,chardet没有足够的特征样本判断编码类型,无需采信检测结果,直接使用你手动整理的映射即可。
内容的提问来源于stack exchange,提问作者kroppian
相关产品推荐
相关产品推荐

