Jas*_*ith 27 python unicode json truncate
给定Unicode字符串和这些要求:
例如,iPhone推送服务需要JSON编码,最大总包数为256字节.
截断字符串以便重新编码为有效的Unicode并且它显示得相当正确的最佳方法是什么?
(人类语言理解不是必需的 - 截断的版本看起来很奇怪,例如对于孤立的组合字符或泰语元音,只要软件在处理数据时不会崩溃.)
也可以看看:
Den*_*ach 29
def unicode_truncate(s, length, encoding='utf-8'):
encoded = s.encode(encoding)[:length]
return encoded.decode(encoding, 'ignore')
Run Code Online (Sandbox Code Playgroud)
下面是unicode字符串的示例,其中每个字符用UTF-8中的2个字节表示:
>>> unicode_truncate(u'?????', 5)
u'\u0430\u0431'
Run Code Online (Sandbox Code Playgroud)
UTF-8的一个特性是它很容易重新同步,即在编码的字节流中很容易找到unicode字符边界.您需要做的就是以最大长度剪切编码的字符串,然后从末尾向后移动,删除大于127的任何字节 - 这些字节是多字节字符的一部分或开头.
正如现在所写,这太简单了 - 将擦除到最后的ASCII字符,可能是整个字符串.我们需要做的是检查没有截断的双字节(开头110yyyxx
)三字节(1110yyyy
)或四字节(11110zzz
)
Python 2.6实现清晰的代码.优化不应成为问题 - 无论长度如何,我们只检查最后1-4个字节.
# coding: UTF-8
def decodeok(bytestr):
try:
bytestr.decode("UTF-8")
except UnicodeDecodeError:
return False
return True
def is_first_byte(byte):
"""return if the UTF-8 @byte is the first byte of an encoded character"""
o = ord(byte)
return ((0b10111111 & o) != o)
def truncate_utf8(bytestr, maxlen):
u"""
>>> us = u"????????????"
>>> s = us.encode("UTF-8")
>>> trunc20 = truncate_utf8(s, 20)
>>> print trunc20.decode("UTF-8")
??????
>>> len(trunc20)
18
>>> trunc21 = truncate_utf8(s, 21)
>>> print trunc21.decode("UTF-8")
???????
>>> len(trunc21)
21
"""
L = maxlen
for x in xrange(1, 5):
if is_first_byte(bytestr[L-x]) and not decodeok(bytestr[L-x:L]):
return bytestr[:L-x]
return bytestr[:L]
if __name__ == '__main__':
# unicode doctest hack
import sys
reload(sys)
sys.setdefaultencoding("UTF-8")
import doctest
doctest.testmod()
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6151 次 |
最近记录: |