3

unichr(0x10000)当cpythonValueError编译时没有--enable-unicode=ucs4.

是否有语言内置或核心库函数可以将任意 unicode 标量值或代码点转换为unicode无论程序运行在哪种 python 解释器上都可以工作的字符串?

4

1 回答 1

8

是的,给你:

>>> unichr(0xd800)+unichr(0xdc00)
u'\U00010000'

要理解的关键点是unichr()在 Python 解释器的字符串编码中将整数转换为单个代码单元。The Python Standard Library documentation for 2.7.3, 2. Built-in Functions , onunichr() reads,

返回一个字符的 Unicode 字符串,其 Unicode 代码是整数 i.... 参数的有效范围取决于 Python 的配置方式——它可以是 UCS2 [0..0xFFFF] 或 UCS4 [0..0x10FFFF]。ValueError否则被提出。

我强调了“一个字符”,它们在 Unicode 术语中的意思是“一个代码单元”

我假设您使用的是 Python 2.x。Python 3.x 解释器没有内置unichr()函数。取而代之的是 3.3.0 的 Python 标准库文档,2. 内置函数chr()读取,

返回表示其 Unicode 代码点为整数 i.... 的字符的字符串。参数的有效范围是从 0 到 1,114,111(基数为 16 的 0x10FFFF)。

请注意,返回值现在是未指定长度的字符串,而不是具有单个代码单元的字符串。所以在 Python 3.x 中,chr(0x10000)会像你预期的那样运行。它“将任意 unicode 标量值或代码点转换为unicode无论程序运行在哪种 python 解释器上都可以工作的字符串”。

但回到 Python 2.x。如果您用于unichr()创建 Python 2.xunicode对象,并且您使用 0xFFFF 以上的 Unicode 标量值,那么您将提交代码以了解 Python 解释器的unicode对象实现。

unichr()您可以使用尝试标量值、捕获ValueError并使用相应的 UTF-16 代理对再次尝试的函数来隔离这种意识:

def unichr_supplemental(scalar):
     try:
         return unichr(scalar)
     except ValueError:
         return unichr( 0xd800 + ((scalar-0x10000)//0x400) ) \
               +unichr( 0xdc00 + ((scalar-0x10000)% 0x400) )

>>> unichr_supplemental(0x41),len(unichr_supplemental(0x41))
(u'A', 1)
>>> unichr_supplemental(0x10000), len(unichr_supplemental(0x10000))
(u'\U00010000', 2)

string但是您可能会发现将标量转换为 UTF-32 byte 中的 4 字节 UTF-32 值并将此字节解码stringunicode字符串更容易:

>>> '\x00\x00\x00\x41'.decode('utf-32be'), \
... len('\x00\x00\x00\x41'.decode('utf-32be'))
(u'A', 1)
>>> '\x00\x01\x00\x00'.decode('utf-32be'), \
... len('\x00\x01\x00\x00'.decode('utf-32be'))
(u'\U00010000', 2)

上面的代码在 Python 2.6.7 上使用 UTF-16 编码对 Unicode 字符串进行了测试。我没有在 Python 2.x 解释器上对 Unicode 字符串使用 UTF-32 编码进行测试。但是,它应该在具有任何 Unicode 字符串实现的任何 Python 2.x 解释器上保持不变。

于 2012-11-18T00:13:44.100 回答