python中准确获取中文字符串的长度

对于这个问题,我首先百度和Google了,但是结果并不理想,可以说都无法准确获取或很难获取,如果字符串中仅包含中文也还好,如果包含4字节的emoji表情字符怎么办?还有人说用正则表达式获取,但是Unicode标准仍在发展和扩充,兼容性也是有限。

我的想法是,既然一个字符最多占4字节,那就把所有字符都转换为4字节的字符不就行了,这就是UTF-32编码。

UTF-8编码大家都常用,Windows编程中或许还会用用UTF-16,UTF-32估计就很少人用过了,它跟UTF-8一样,也是Unicode的一种编码方式,只不过它一个字符占32位(4字节),这里不再细说,不知道的可以自行百度。

把字符串转成UTF-32也简单,跟其他编码转换一样,首先需要转成Unicode,然后再转成UTF-32:

s = "..."
us = s.decode("utf8")  # 或者为gbk
u32s = us.encode("utf32")

由于转成UTF-32后,python默认会在头部加上4字节的BOM(可以通过codecs.BOM_UTF32查看),所以长度中应该减去BOM的长度:

l = len(u32s)/4-1

这里顺便一说,头部的BOM是可以删除掉的,python能够处理这种情况,如:

u32s = u32s[4:]            # 去掉头部的BOM
us = u32s.decode("utf32")  # 仍然能够正确处理

转成UTF-32后,其他一些字符串处理也能方便的进行,比如之前很难进行的分割,只要按4字节的单位进行分割,分割后再转回原始编码即可。

提供一个准确的字符串转列表函数,把字符串分割为一个一个的字符:

def str2list(s, encoding="utf8"):
    if not isinstance(s, unicode):
        s = s.decode(encoding)
    s = s.encode("utf32")[4:]
    return [s[i*4:i*4+4].decode("utf32") for i in xrange(len(s)/4)]

最后,python3大法好!!python3已经原生支持了3字节、4字节的Unicode字符,len()和list()均能正确处理!

You may also like...

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

扫码去手机上看