Python如何正确打印cp1258越南语字符?

时间:2019-11-01 15:01:17

标签: python encoding

如何在python 3中正确打印越南语cp1258编码的字符?我的终端机似乎不是问题,因为它将在我的代码中正确打印第一个打印语句。我正在尝试将十六进制字符解码为越南语

代码:

import binascii

data = 'tạm biệt'
print(data) # tạm biệt

a = binascii.hexlify(data.encode('cp1258', errors='backslashreplace'))
print(a) # b'745c75316561316d2062695c753165633774'
# if i dont use the error handler here, then I get a UnicodeEncodeError for \u1ea1

print(
    binascii.unhexlify(a).decode('cp1258') # t\u1ea1m bi\u1ec7t
)

2 个答案:

答案 0 :(得分:2)

Python对code page 1258的支持似乎有所遗漏。传统编解码器确实通过组合变音符号来支持越南语,但Python不知道如何将Unicode转换为这些组合。我想您将不得不执行自己的转换。

第一步,请注意unicodedata.normalize('NFD', data)将表示形式分为一个基本字符和一系列变音符号组合。

>>> unicodedata.normalize('NFD', data).encode('utf-8')
b'ta\xcc\xa3m bie\xcc\xa3\xcc\x82t'
>>> '{0:04x}'.format(ord(b'\xcc\xa3'.decode('utf-8')))
'0323'

因此,U + 0323是点下结合的Unicode变音符号,编解码器应该知道该对应 (我在上面链接到的Wikipedia页面显示了与CP1258相同的Unicode字符代码代码点0xF2)。

我对目标编解码器了解不多,无法告诉您如何将它们映射到CP1258,但是,如果幸运的话,Python编解码器中已经存在某种映射。

我的Mojave MacOS上的

iconv似乎可以毫不费力地进行转换:

$ iconv -t cp1258 <<<'tạm biệt' | xxd
00000000: 7461 f26d 2062 69ea f274 0a              ta.m bi..t.

由此看来,变音符号可以直接作为后缀应用-61a,如上所述,f2是组合变音符号,将点放在下面主字形。

如果您的iconv工作正常,那么一种快速而肮脏的解决方法可能是将其作为subprocess运行。

import subprocess

converted = subprocess.run(['iconv', '-t', 'cp1258'],
    input=data.encode('utf-8'), stdout=subprocess.PIPE).stdout

如果我的理解是正确的,则应将其确实报告为Python中的错误。如果要声明自己支持该编解码器,则绝对应该知道如何在该编解码器和Unicode之间往返。

答案 1 :(得分:0)

我知道了。用unicode-escape解码就可以了。

import binascii

data = u'tạm biệt'
print(data) # tạm biệt

a = binascii.hexlify(data.encode('cp1258', errors='backslashreplace'))
print(a) # b'745c75316561316d2062695c753165633774'
# if i dont use the error handler here, then I get a UnicodeEncodeError for \u1ea1

print(
    binascii.unhexlify(a).decode('unicode-escape') # tạm biệt
)