我想将u"an arbitrary unicode string"
拆分成300字节的块,而不会破坏任何字符。字符串将被写入使用unicode_string.encode("utf8")
的utf8的套接字。我不想破坏任何角色。我该怎么做?
答案 0 :(得分:10)
UTF-8专为此而设计。
def split_utf8(s, n):
"""Split UTF-8 s into chunks of maximum length n."""
while len(s) > n:
k = n
while (ord(s[k]) & 0xc0) == 0x80:
k -= 1
yield s[:k]
s = s[k:]
yield s
未经测试。但是你找到了一个分裂的地方,然后回溯到你到达角色的开头。
但是,如果用户可能想要查看单个块,则可能需要在字形集群边界上进行拆分。这要复杂得多,但并不棘手。例如,在"é"
中,可能不想将"e"
和"´"
分开。或者你可能不在乎,只要他们最终再次陷入困境。
答案 1 :(得分:5)
UTF-8有一个特殊属性,所有连续字符都是0x80
- 0xBF
(从第10位开始)。因此,请确保不要在一个之前拆分。
有些事情:
def split_utf8(s, n):
if len(s) <= n:
return s, None
while ord(s[n]) >= 0x80 and ord(s[n]) < 0xc0:
n -= 1
return s[0:n], s[n:]
应该这样做。
答案 2 :(得分:2)
测试。
def split_utf8(s , n):
assert n >= 4
start = 0
lens = len(s)
while start < lens:
if lens - start <= n:
yield s[start:]
return # StopIteration
end = start + n
while '\x80' <= s[end] <= '\xBF':
end -= 1
assert end > start
yield s[start:end]
start = end
答案 3 :(得分:0)
如果你可以确保你的字符的utf-8表示只有2个字节长,那么将unicode字符串拆分成150个字符的块应该是安全的(对于大多数欧洲编码,这应该是正确的)。但是utf-8是可变宽度编码。因此可能会将unicode字符串拆分为单个字符,将每个字符串转换为utf-8并填充缓冲区,直到达到最大块大小...这可能效率低,如果高吞吐量是必须的话就会出现问题...
答案 4 :(得分:-2)
使用unicode编码,其设计具有每个字符的固定长度,例如utf-32
:
>>> u_32 = u'Юникод'.encode('utf-32')
>>> u_32
'\xff\xfe\x00\x00.\x04\x00\x00=\x04\x00\x008\x04\x00\x00:\x04\x00\x00>\x04\x00\x
004\x04\x00\x00'
>>> len(u_32)
28
>>> len(u_32)%4
0
>>>
编码后你可以发送任何大小的块(大小必须是4个字节的倍数)而不会破坏字符