Python 3.8:将非 ascii 字符转义为 unicode

时间:2021-04-13 13:14:07

标签: python unicode encoding

我有可以包含非 ASCII 字符的输入和输出文本文件。有时我需要转义它们,有时我需要编写非 ascii 字符。基本上,如果我得到“Bürgerhaus”,我需要输出“B\u00FCrgerhaus”。如果我得到“B\u00FCrgerhaus”,我需要输出“Bürgerhaus”。

一个方向没问题:

>>> s1 = "B\u00FCrgerhaus"
>>> print(s1)
Bürgerhaus

然而在另一个方向我没有得到预期的结果('B\u00FCrgerhaus'):

>>> s2 = "Bürgerhaus"
>>> s2_trans = s2.encode('utf8').decode('unicode_escape')
>>> print(s2_trans)
Bürgerhaus

我读到 unicode-escape 需要 latin-1,我尝试将其编码为它,但这也没有产生结果。我做错了什么?

(PS:感谢 Matthias 提醒我第一个示例中的转换不是必需的。)

2 个答案:

答案 0 :(得分:1)

你可以这样做:

charList=[]
s1 = "Bürgerhaus"

for i in [ord(x) for x in s1]:
    # Keep ascii characters, unicode characters 'encoded' as their ordinal in hex
    if i < 128:  # not sure if that is right or can be made easier!
        charList.append(chr(i))
    else:
        charList.append('\\u%04x' % i )

res = ''.join(charList)
print(f"Mixed up sting: {res}")

for myStr in (res, s1):
    if '\\u' in myStr:
        print(myStr.encode().decode('unicode-escape'))
    else:
        print(myStr)

出:

Mixed up sting: B\u00fcrgerhaus
Bürgerhaus
Bürgerhaus

说明:

我们要将每个字符转换为对应的 Unicode 代码点。

print([(c, ord(c)) for c in s1])
[('B', 66), ('ü', 252), ('r', 114), ('g', 103), ('e', 101), ('r', 114), ('h', 104), ('a', 97), ('u', 117), ('s', 115)]

常规的 ASCII 字符十进制值 < 128,更大的值,如 Eur-Sign、德国变音符号...得到的值 >= 128(详细表 here)。

现在,我们将使用相应的 unicode 表示对所有 >= 128 的字符进行“编码”。

答案 1 :(得分:0)

您只能将 decode() 个字节串 (bytes) 转换为 [unicode] 字符串,相反,encode() [unicode] 字符串转换为 bytes

因此,如果您想解码用 unicode-escape 转义的字符串,您需要先将 (encode()) 转换为字节字符串,例如,使用 latin1 作为您在问题中所写.

>>> encoded_str = 'B\\xfcrgerhaus'
>>> encoded = encoded_str.encode('latin-1')
>>> encoded
b'B\\xfcrgerhaus'
>>> encoded.decode('unicode-escape')
'Bürgerhaus'
>>> _.encode('unicode-escape')
b'B\\xfcrgerhaus'
>>> _ == encoded
True

另见:how do I .decode('string-escape') in Python3?

相关问题