将unicode字符串拆分为300个字节的块,而不会破坏字符

时间:2011-05-18 10:48:47

标签: python string utf-8

我想将u"an arbitrary unicode string"拆分成300字节的块,而不会破坏任何字符。字符串将被写入使用unicode_string.encode("utf8")的utf8的套接字。我不想破坏任何角色。我该怎么做?

5 个答案:

答案 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个字节的倍数)而不会破坏字符