我需要一次一个字符地遍历一个Python字符串,但是一个简单的“for”循环给出了UTF-16代码单元:
str = "abc\u20ac\U00010302\U0010fffd"
for ch in str:
code = ord(ch)
print("U+{:04X}".format(code))
打印出:
^{pr2}$当我想要的是:
U+0061
U+0062
U+0063
U+20AC
U+10302
U+10FFFD
有没有办法让Python给出Unicode代码点的序列,而不管字符串实际上是如何编码的?我在这里测试Windows,但是我需要在任何地方都能工作的代码。它只需要在Python3上运行,我不关心Python2.x
到目前为止,我所能想到的最好的是:
import codecs
str = "abc\u20ac\U00010302\U0010fffd"
bytestr, _ = codecs.getencoder("utf_32_be")(str)
for i in range(0, len(bytestr), 4):
code = 0
for b in bytestr[i:i + 4]:
code = (code << 8) + b
print("U+{:04X}".format(code))
但我希望有更简单的方法。在
(对于精确的Unicode术语,学究式的吹毛求疵会被一条线索狠狠地揍了一顿。我想我已经清楚地表明了我的目标,请不要用“但是UTF-16在技术上也是Unicode”之类的论点浪费空间。)
Python通常在内部将unicode值存储为UCS2。UTF-32\U00010302字符的UTF-16表示是\UD800\UDF02,这就是您得到这个结果的原因。在
也就是说,有些python构建使用UCS4,但是这些构建彼此不兼容。在
看看here。在
在使用窄Unicode内部版本的Python 3.2.1上:
您发现了什么(UTF-16编码):
^{pr2}$绕道而行:
Python 3.3更新:
现在它的工作方式与OP期望的一样:
如果将字符串创建为unicode对象,它应该能够一次自动断开一个字符。E、 g.:
Python2.6:
我收到了:
^{pr2}$Python3.2:
它对我有用:
^{pr2}$另外,我发现了this link,它解释了行为是正确工作的。如果字符串来自文件等,则可能需要先对其进行解码。在
更新:
我发现了一个很有见地的explanation here。内部Unicode表示大小是一个编译时选项,如果在16位平面之外使用“宽”字符,则需要自己构建python来消除限制,或者使用本页中的一种解决方法。显然,正如我在上面遇到的那样,许多Linux发行版已经为您做了这项工作。在
相关问题 更多 >
编程相关推荐