美文网首页程序员
python计算含汉字字符串的长度及截断(1个汉字算2个字符)

python计算含汉字字符串的长度及截断(1个汉字算2个字符)

作者: 玩物励志老乐 | 来源:发表于2020-11-08 17:19 被阅读0次

    需求

    我做的项目里,遇到这么一个需求:客户用的sql server版本比较老,对中文字符的计数还是停留在1个汉字为2个字符的水平。

    分析

    都2020年了,怎么还有不用UTF8做字符集的应用的系统呢?
    但是也没办法,毕竟客户的需求,是必须要满足的。
    python的默认字符集是UTF-8,常规思路是,程序代码通过正则匹配Unicode编码范围,把汉字的个数统计出来,然后再为每个中文字符长度+1
    不过我发现还有一种更简单的方法,仅仅通过减法就能准确算出汉字的长度。

    代码示例

    # 按照一个汉字为两个字符计数
    def chn_length(text):
        if text is None:
            return 0
        lenText = len(text)
        lenText_utf8 = len(text.encode('utf-8'))
        # utf-8一个汉字占3个字符,减去原计数就是多出来的2/3,再除以2就是增量。再加回去即可
        size = int((lenText_utf8 - lenText) / 2 + lenText)
        return size
    
    a = '你好啊123'
    print(chn_length(a))
    # 结果
    # 9
    

    讲解

    1. 首先把目标字符串的长度计算出来,由于python默认utf8编码,一个汉字占1个字符,故此时长度(lenText)为6;
    2. 显式的,以UTF8编码,转成python字节码,这时每个汉字会占3个字符。那我们再次计算长度(lenText_utf8)为12,即3(汉字个数) x 3 + 3(字母个数);
    3. lenText_utf8 - lenText 得出的结果就是utf8格式下,多出来的字符数,也就是每个汉字额外占用的2个字符的空间
    4. 由于每一个汉字都额外占用2个字符,那我们可以给这些额外长度除以2,也就得出了每个汉字只额外占用1个字符的差量;
    5. 把差量和lenText相加,就得到了我们需要的,一个汉字占2个字符的结果。

    小结

    数学很奇妙,我们通过简单的减法运算,就代替了正则匹配汉字unicode码这种效率低下的做法。
    核心思想:在unicode编码体系下,一个汉字占3个字符。我们只需要(3-1)/2+1就能得到一个汉字占2个字符的结果

    one more thing

    客户又提出,需要我按指定长度截断这段字符,需要注意的是不能出现半个汉字导致的乱码。
    其实呢,截断也很简单。

    v = '你好123'
    x = 3
    v.encode("gbk")[0:x].decode("gbk")
    

    其实就是先把字符串按照gbk编码(1个汉字=2个字节),然后截断,然后再用gbk解码即可。
    上面运行的结果是:你好1

    相关文章

      网友评论

        本文标题:python计算含汉字字符串的长度及截断(1个汉字算2个字符)

        本文链接:https://www.haomeiwen.com/subject/qlravktx.html