【发布时间】:2011-11-21 14:02:14
【问题描述】:
我需要一次遍历一个字符的 Python 字符串,但是一个简单的“for”循环给了我 UTF-16 代码单元:
str = "abc\u20ac\U00010302\U0010fffd"
for ch in str:
code = ord(ch)
print("U+{:04X}".format(code))
打印出来的:
U+0061
U+0062
U+0063
U+20AC
U+D800
U+DF02
U+DBFF
U+DFFD
当我想要的是:
U+0061
U+0062
U+0063
U+20AC
U+10302
U+10FFFD
有没有办法让 Python 给我 Unicode 代码点的序列,而不管字符串实际上是如何编码的?我在这里在 Windows 上进行测试,但我需要可以在任何地方工作的代码。它只需要在 Python 3 上工作,我不关心 Python 2.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 2 上,像你一样狭窄的构建)是
string.encode('utf-32-be')然后for chars in (string[n:n+4] for n in range(0, len(string), 4)):然后code = reduce(lambda x, y: (x << 8) + y, (ord(ch) for ch in chars)) -
我认为自己在精确的 Unicode 术语方面是一个迂腐的吹毛求疵者,并认为你已经把自己说得很清楚了 ;-)
-
sys.maxunicode是“一个整数,给出了 Unicode 字符支持的最大代码点。”如果您使用的是 UTF-16 版本的 Python,非 BMP 字符可能不支持 unicode 字符串迭代。我在stackoverflow.com/questions/7495150/… 提出了这个问题。
标签: python unicode python-3.x