82

在 Python API 中,有没有办法提取单个字符的 unicode 代码点?

编辑:如果重要的话,我使用的是 Python 2.7。

4

5 回答 5

86

如果我正确理解您的问题,您可以这样做。

>>> s='㈲'
>>> s.encode("unicode_escape")
b'\\u3232'

将 unicode 转义码显示为源字符串。

于 2011-09-03T04:39:09.717 回答
67
>>> 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
于 2011-09-03T04:28:20.683 回答
13

事实证明,要做到这一点相当棘手:Python 2 和 Python 3 在从字符串中提取 Unicode 代码点时存在一些微妙的问题。

在 Python 3.3 之前,可以以两种模式之一编译 Python:

  1. 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 及更高版本在所有操作系统上的默认设置。

  1. 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'
于 2017-02-16T00:46:14.430 回答
12

通常,您只需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().

于 2011-09-03T04:55:06.653 回答
4

蟒蛇2

>>> print hex(ord(u'人'))
0x4eba
于 2019-07-04T03:37:07.297 回答