如何通过在字符串中使用 \u 或 \U 转义来正确表示 python3 (3.6.1+) 中的补充 unicode 字符

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

最近我在学习python,遇到了python 3中unicode转义文字的问题。

似乎和 Java 一样,\u 转义符被解释为 Java 使用的 UTF-16 代码点,但问题来了:

例如,如果我尝试放置一个 3 字节的 utf-8 字符,如“♬”(https://unicode-table.com/en/266C/),甚至是补充性 unicode 字符,如“𠜎”(https ://unicode-table.com/en/2070E/)按普通字符串中的\uXXXX或\UXXXXXXXX格式,如下:

print('\u00E2\u99AC')  # UTF-8, messy code for sure
print('\U00E299AC')    # UTF-8, with 8 bytes \U, (unicode error) for sure
print('\u266C')        # UTF-16 BE, music note appeares
# from which I suppose \u and \U function the same way they should do in Java
# (may be a little different since they function like macro in Java, and can be useed in comments)

# However, while print('\u266C') gives me '♬','\u266C' == '♬' is equal to false
# which is true in Java semantics.
# Further more, print('\UD841DF0E') didn't give me '𠜎' : (unicode error) 'unicodeescape' codec can't decode bytes in position 0-9: illegal Unicode character
# which I suppose it should be, so it appears to me that I may get it wrong
# Here again : print('\uD841\uDF0E')  # Error, 'utf-8' codec can't encode characters in position 0-1: surrogates not allowed

print('\xD8\x41\xDF\x0E')  # also tried this, messy code
# maybe UTF-16 LE?
print('\u41D8\u0EDF')  # messy code
print('\U41D80EDF')  # error

所以,我可以看到Python“不支持补充转义文字”,而且它的行为也很奇怪。

嗯,我已经知道解码和编码这些字符的正确方法了:

s_decoded = '\\xe2\\x99\\xac'.encode().decode('unicode-escape')\
               .encode('latin-1').decode('utf-8')
print(b'\xf0\xa0\x9c\x8e'.decode('utf-8'))
print(b'\xd8\x41\xdf\x0e'.decode('utf-16 be'))
assert s_decoded == '♬'

但仍然不知道如何使用 \u 和 \U 转义文字正确执行此操作。希望有人能指出我做错了什么以及它与Java的方式有何不同,谢谢!

顺便说一句,我的环境是PyCharm win,python 3.6.1,源码编码为UTF-8

python unicode encoding utf-8 utf-16
1个回答
2
投票

Java 使用代理代码点(UTF-16 代码单元)来表示基本多语言平面(BMP、U+0000 到 U+FFFF)之上的值。 Python 没有。 使用 Unicode 代码点的确切值,而不是其 UTF-16 代理项对。

\u
需要4个十六进制数字,可以处理基本多语言平面(BMP)中从0到0xFFFF的Unicode代码点。
\U
需要8个十六进制数字,可以处理0到0x10FFFF。如果需要,请确保使用前导零。
\x
也可以使用,但只能处理代码点 0 - 0xFF。

>>> print('\u266c') # U+266C
♬
>>> print('\U0002070E') # U+2070E.  Python is not Java
𠜎
>>> '\u266c' == '♬'
True
>>> '\U0002070E' == '𠜎'
True
>>> '\x41' == 'A'
True
© www.soinside.com 2019 - 2024. All rights reserved.