2017-02-28 [長年日記]

カスタムなエンコードエラー対処 [Python]

JavaやScalaで前にやったのと同じ。

prima materia - diary : MalformedInputException


Pythonはcodecsやdecode/encodeにerrors引数で都度指定できる。

# 正しくないバイトシークェンスを作る
err_bytes = 'あいう'.encode('utf-8')
err_bytes = err_bytes[:3] + err_bytes[4:]

err_bytes.decode('utf8')
# => raise UnicodeDecodeError: 'utf-8' codec can't decode byte 0x81 in position 3: invalid start byte
# same as err_bytes.decode('utf8', errors='strict')

err_bytes.decode('utf8', errors='ignore')
# => 'あう'

err_bytes.decode('utf8', errors='replace')
# => 'あ��う'


ほかには、

with open(file_name, 'r', errors='ignore') as f:
    ...

とか

with codecs.open(file_name, 'w', 'cp932', errors='ignore') as f:
    ...

などとする。


さて、replaceを指定したときになんの文字で置き換えるかを指定したい、というのが今回のお話。

import codecs

def tohu_err_handler(er: UnicodeError):
    if isinstance(er, UnicodeEncodeError):
        return '□'.encode(er.encoding), er.end
    else:
        return '□', er.end

codecs.register_error('tohu', tohu_err_handler)

これで errors 引数に 'tohu’ が指定できる。

err_bytes.decode('utf-8', errors='tohu')
# => 'あ□□う'


コードはPython3系です。