处理命令行参数中的unicode字符

问题描述 投票:0回答:1

我在Raspberry Pi(基于Raspbian Debian的Linux OS)上有一个项目,在这里我必须将命令行参数传递给Python 3程序。我需要能够传递unicode字符串。

我不确定应该如何设置。显然,在将数据传递到Python之前,命令行字符串要进行几次转换。

首先,当我在终端会话中按所需的击键时,我可以正确看到Unicode字符。这是一些测试代码:

$ echo "ā" > test.txt
$ cat test.txt
ā
$ hexdump test.txt 
0000000 81c4 000a                              
0000003

[那个0x81c4字或两字节序列0xc4 + 0x81被“ā”编码为UTF-8。

现在,如果我尝试将相同的字符传递给Python,则会得到两个字符的字符串,其中包含奇怪的字符代码:

import sys
param = sys.argv[1]
print([hex(ord(char)) for char in param])

$ python test.py ā
['0xdcc4', '0xdc81']

[可以注意到字符代码与0xc4 + 0x81字节序列有关,但是这里每个字节都添加了0xdc00。

如果我进入交互式控制台,则Unicode字符操作与普通字符相同:

>>> txt = 'ā'
>>> len(txt)
1
>>> hex(ord(txt[0]))
'0x101'

0x101是字符“ā”的正确代码点。

所以,我的问题是,如何才能可靠地将两字符['0xdcc4', '0xdc81']字符串转换为在所有平台上都可以使用的一字符字符串“ā”?

python python-3.x command-line-arguments unicode-string
1个回答
0
投票

我不确定这发生在哪一点,但是命令行参数显然应该只包含ASCII字符,并将字节数组解码为字符串,使用bytes.decode(encoding, errors)

param = b'\xc4\x81'.decode('ASCII', 'surrogateescape')
print(param == '\udcc4\udc81') # True

当解码器偶然发现一个非ASCII字符时,它将根据所选的错误处理程序处理解码。在这种情况下,surrogateescape错误处理程序将字节替换为范围从U + DC80到U + DCFF的单个代理代码。

因此,解决此问题的方法是使用相同的surrogateescape错误处理程序将错误解码的字符串编码回字节数组,然后将其解码为utf-8

import sys
param = sys.argv[1]
param_unicode = param.encode('ASCII', 'surrogateescape').decode('utf-8')
print(param_unicode)

$ python test.py ā
ā

但是,如果确实确实总是使用ASCII编码来解码命令行参数,则应进行验证。也许它在不同的平台上是不同的并且是可配置的。

© www.soinside.com 2019 - 2024. All rights reserved.