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

标签 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
)

最佳答案

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 变音符号,编解码器应该知道这种对应关系(我上面链接到的维基百科页面显示了 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,一个快速但肮脏的解决方法可能是将其作为子进程运行。

import subprocess

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

如果我的理解是正确的,这确实应该被报告为Python中的一个错误。如果它想声明它支持它,它肯定应该知道如何在该编解码器和 Unicode 之间往返。

关于Python如何正确打印cp1258越南语字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58661415/

相关文章:

python - 在 Python 中绘制 3D 圆柱面图

python - 1 liner 'pythonic' 返回集合而不是列表的代码

javascript - 返回值的编码

c - 多字节序列的长度(以字节为单位)、(unicode)代码点、字符和光标位置

PHP。从命令行和浏览器调用 shell_exec 时的编码不同

Python 3 如何从标准输入上的文件生成 md5 哈希?

python - Tkinter 文本 selection_get() 错误

python - 使用 BeautifulSoup 从 HTML 创建 JSON 结构

PHPMailer:阿拉伯语(非英语)字符的主题名称

java - URI 中的非法字符