在 Python API 中,有没有办法提取单个字符的 unicode 代码点?
编辑:如果重要的话,我使用的是 Python 2.7。
在 Python API 中,有没有办法提取单个字符的 unicode 代码点?
编辑:如果重要的话,我使用的是 Python 2.7。
如果我正确理解您的问题,您可以这样做。
>>> s='㈲'
>>> s.encode("unicode_escape")
b'\\u3232'
将 unicode 转义码显示为源字符串。
>>> ord(u"ć")
263
>>> u"café"[2]
u'f'
>>> u"café"[3]
u'\xe9'
>>> for c in u"café":
... print repr(c), ord(c)
...
u'c' 99
u'a' 97
u'f' 102
u'\xe9' 233
事实证明,要做到这一点相当棘手:Python 2 和 Python 3 在从字符串中提取 Unicode 代码点时存在一些微妙的问题。
在 Python 3.3 之前,可以以两种模式之一编译 Python:
sys.maxunicode == 0x10FFFF
在这种模式下,Python 的 Unicode 字符串支持从 U+0000 到 U+10FFFF 的全范围 Unicode 码位。一个代码点由一个字符串元素表示:
>>> import sys
>>> hex(sys.maxunicode)
'0x10ffff'
>>> len(u'\U0001F40D')
1
>>> [c for c in u'\U0001F40D']
[u'\U0001f40d']
这是 Linux 上 Python 2.7 以及 Python 3.3 及更高版本在所有操作系统上的默认设置。
sys.maxunicode == 0xFFFF
在这种模式下,Python 的 Unicode 字符串只支持从 U+0000 到 U+FFFF 的 Unicode 码位范围。从 U+10000 到 U+10FFFF 的任何代码点都使用 UTF-16 编码中的一对字符串元素表示:
>>> import sys
>>> hex(sys.maxunicode)
'0xffff'
>>> len(u'\U0001F40D')
2
>>> [c for c in u'\U0001F40D']
[u'\ud83d', u'\udc0d']
这是 macOS 和 Windows 上 Python 2.7 的默认设置。
这种运行时差异使得编写 Python 模块以将 Unicode 字符串作为一系列代码点来操作非常不方便。
为了解决这个问题,我贡献了一个新codepoints
模块PyPI
:
https://pypi.python.org/pypi/codepoints/1.0
该模块通过公开 API 以将 Unicode 字符串与代码点列表相互转换来解决问题,而不管sys.maxunicode
::的底层设置如何
>>> hex(sys.maxunicode)
'0xffff'
>>> snake = tuple(codepoints.from_unicode(u'\U0001F40D'))
>>> len(snake)
1
>>> snake[0]
128013
>> hex(snake[0])
'0x1f40d'
>>> codepoints.to_unicode(snake)
u'\U0001f40d'
通常,您只需ord(character)
查找字符的代码点。不过为了完整起见,Unicode Supplementary Multilingual Plane 中的宽字符在狭窄的 Python 构建中表示为代理对(即两个代码单元),所以在这种情况下,我经常需要做这个小工作:
def get_wide_ordinal(char):
if len(char) != 2:
return ord(char)
return 0x10000 + (ord(char[0]) - 0xD800) * 0x400 + (ord(char[1]) - 0xDC00)
不过,这在大多数应用程序中很少见,因此通常只需使用ord()
.
蟒蛇2
>>> print hex(ord(u'人'))
0x4eba