Google App Engine使用Python 2.5.2,显然在启用UCS4的情况下。但GAE数据存储在内部使用UTF-8。所以,如果你存储U '\ ud834 \ udd0c'(长2)到数据存储,当你找回它,你会得到 '\ U0001d10c'(长度为1)。我试图在存储它之前和之后给出相同结果的方式来计算字符串中的Unicode字符数。所以我想,我接受它,计算它的长度,并把它的数据存储之前,尽快恢复正常的字符串(从u“\ ud834 \ udd0c”到“\ U0001d10c”)。我知道我可以将它编码为UTF-8,然后再解码,但有没有更直接/更高效的方法?如何在Python中获得可靠的unicode字符数?
8
A
回答
4
我知道我可以只是将其编码成UTF-8,然后再进行解码
是的,这是通常的成语来修复该问题,当你在有“UTF-16替代品UCS-4字符串“输入。但随着机械蜗牛说,该输入是畸形,你应该可以固定在任何偏好产生了。
有没有更简单的/有效的方式?
嗯......你可以用正则表达式做手工,如:
re.sub(
u'([\uD800-\uDBFF])([\uDC00-\uDFFF])',
lambda m: unichr((ord(m.group(1))-0xD800<<10)+ord(m.group(2))-0xDC00+0x10000),
s
)
当然不是更简单...我也有我的怀疑是否它实际上更高效!
2
不幸的是,早于3.3版本的CPython解释器的行为取决于它是用“窄”还是“宽”Unicode支持构建的。因此,相同的代码(例如致电len
)在标准解释器的不同版本中可能会有不同的结果。示例请参见this question。 “窄”解释器在内部存储16位代码单元(UCS-2),而“宽”解释器在内部存储32位代码单元(UCS-4) 。代码分 U + 10000及以上(基础多语言平面以外)在“狭义”口译人员上有两个len
,因为需要两个UCS-2代码单元来表示它们(使用代理),这就是len
措施。上的“宽”构建仅单个UCS-4代码单元需要非BMP代码点,所以对于那些构建len
是一个这样的代码点。
我已经确认,下面的代码处理所有unicode
字符串,不管它们是否包含代理对,并且在CPython 2.7中都适用于狭窄和广泛的构建。 (可以说,在一个广泛的口译员中指定一个像u'\ud83d\udc4d'
这样的字符串反映了肯定的愿望,即代表完整的替代代码点与部分字符代码单元不同,因此不会自动成为要纠正的错误,这是一个边缘情况,通常不是所需的用例)
以下使用的@invoke
技巧是避免重复计算而不在模块的__dict__
中添加任何内容的方法。
invoke = lambda f: f() # trick taken from AJAX frameworks
@invoke
def codepoint_count():
testlength = len(u'\U00010000') # pre-compute once
assert (testlength == 1) or (testlength == 2)
if testlength == 1:
def closure(data): # count function for "wide" interpreter
u'returns the number of Unicode code points in a unicode string'
return len(data.encode('UTF-16BE').decode('UTF-16BE'))
else:
def is_surrogate(c):
ordc = ord(c)
return (ordc >= 55296) and (ordc < 56320)
def closure(data): # count function for "narrow" interpreter
u'returns the number of Unicode code points in a unicode string'
return len(data) - len(filter(is_surrogate, data))
return closure
assert codepoint_count(u'hello \U0001f44d') == 7
assert codepoint_count(u'hello \ud83d\udc4d') == 7
相关问题
- 1. Python/Mako:如何获得unicode字符串/字符正确解析?
- 2. 如何获得Unicode字符的字形unicode表示
- 3. 如何在Python中提取数据时获取unicode字符串?
- 4. 无法获得UNICODE字符
- 5. 如何在Python中的字符串中获得°字符?
- 6. 如何获得iPhone的可靠定位
- 7. 如何获得可靠的BroadcastReceiver
- 8. 如何获得目标中的随机Unicode字符C
- 9. Python中通过 '混帐击' 打印Unicode字符串获得 'UnicodeEncodeError'
- 10. 如何获得DBD :: Pg可靠超时?
- 11. __str__中的Python unicode字符
- 12. 如何在一个python字符串中使用Unicode字符
- 13. Unicode字符串为Unicode字符,Python 3
- 14. 得到可靠的IPv6地址在Python
- 15. 如何在Cassandra中获得可靠的插入时间?
- 16. Python中的Unicode:如何测试针对unicode字符串
- 17. 如何获得数字和在python
- 18. 如何在Bash中获取Unicode字符或字符值?
- 19. 拆分字符串,unicode,unicode,python中的字符串
- 20. Python 3中的Unicode字符与Python 2
- 21. Python - pyparsing unicode字符
- 22. 如何将unicode数组转换为Python中的字符串
- 23. Python中,字符串,Unicode字符
- 24. 在Haskell中,如何获得UTF8字符串中的字节数?
- 25. 在Unicode中将unicode字符串转换为可用的unicode
- 26. Android的InputMethodService - 如何获取unicode字符?
- 27. 如何获取Unicode字符的代码?
- 28. 如何在Java中得到Unicode字符的
- 29. python获取unicode字符串大小
- 30. 如何通过python解码unicode字符?
不要试图存储'u'\ ud834 \ udd0c''。代理不是有效的unicode代码点,所以你不应该依赖它们被保存在字符串中,或长度正常工作。 –
澄清:Python中的u'blah''概念上代表了一系列Unicode代码点。所以你不应该把UTF-16的二进制表示放入它们中。 –
如果您从您的问题中删除了关于编码和解码的问题,并将其添加为答案,我可能会赞成它,因为我认为这是获得您要求的最正确的方法。 – SingleNegationElimination