我有可以包含非 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 提醒我第一个示例中的转换不是必需的。)
答案 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