对于这个问题,我首先百度和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()均能正确处理!