python 中英混合字符串格式对齐所引发的思考

对字符串非中文格式化,我们常用的方式是通过print 方式下的右对齐 n%s(左对齐-n%s)或者ljust\rjust;

但上面存在一个缺点就是对于含有中文字符串的处理是不兼容,导致打印出来格式还是没有进行对齐的;


补充下rjust的处理规则:

1. 通过len获取字符串的长度,len的实现方式是对不同的字符进行解码为unicode,再计算unicode所占的字节长度;

2. " "* (width - len) + argu,即补齐相减后的长度的空格,连接原有字符串后返回

主要原因是:在终端展示的时候并不是中文并没有按照三个字符宽的长度去展示,按照等宽字符,每个中文字符占的就是两个英文字母(终端或者文件上面为什么占用的两个字母宽度?)


得到的结果如下:


字符串"中文"在rjust进行对齐处理的因为是utf编码,每个字符的长度(1-6个字节),导致在取字符串长度的时候取的长度是3个字节;


所以python提供API不满足中文的对齐方式,需要自行编写对齐函数进行处理;

在编写之前引入几篇文章关于编码的意义;


既然unicode已经可以表达,为什么不统一使用unicode来处理,还需要在出现编码为utf-8和gbk的方式 ?

unicode所使用的二进制的方式去表达一个字符编码,却没有规定所使用的存储和传输方式,即规定字库的一种实现形式;

而后来utf-8则规定了该字符集的一种物理存储方式和Unicode序号的转换关系,规范了字符集的存储方式,规范了存储空间;



实现代码如下:

def is_chinese(uchar):

    """判断一个unicode是否是汉字"""

    if uchar >= u'\u4e00' and uchar <= u'\u9fa5':

        return True

    else:

        return False

 

def align( text, width, just = "left" ):  

    stext = str(text)

    utext = stext.decode("utf-8")  #对字符串进行转码

    cn_count = 0

    for u in utext:

        if is_chinese(u):

            cn_count += 2 # 计算中文字符占用的宽度

        else:

            cn_count += 1  # 计算英文字符占用的宽度

    if just == "right":

        return " " * (width - cn_count ) + stext  

    elif just == "left":

        return stext + " " * ( width - cn_count )


def string_ljust( text, width ):

    return align( text, width, "left" )


def string_rjust( text, width ):

    return align( text, width, "right" )


print "str %s|" % string_rjust( "中文", 10 ).decode( "utf-8" ).encode( "gb18030" )

print "str %s|" % string_rjust( "ab", 10 ).decode( "utf-8" ).encode( "gb18030" )

print "str %s|" % string_rjust( "a中文", 10 ).decode( "utf-8" ).encode( "gb18030" )

得到效果如下:



编码魔爪在程序猿的世界无处不在,只要其中一个编码过程不统一都会产生乱码的情况;

经常出现同事纠结在于从db里面获取数据的时候出现乱码问题,或者导数据导到db里面的时候出现乱码问题;

1. mysql的db创建需要设置编码,进行数据获取需要设置编码;

2. 不同的客户端邮件发送再到打开文件需要统一字符编码;

3. 前端页面展示需要字符编码;


遇到问题时可以多猜测和验证会有编码的地方,然后通过源码去分析清楚问题的存在;

这篇文章主要解决了当前的问题,再发散性地去延伸到字符编码的问题;

附录:

utf-8和unicode相关的转换关系

http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html


附上中文在unicode的编码范围

http://jicheng.tw/hanzi/unicode.html?s=4E00&e=9FA5


字符集和字符编码:

http://cenalulu.github.io/linux/character-encoding/

你可能感兴趣的:(python 中英混合字符串格式对齐所引发的思考)