中文print对齐

󰃭 2017-03-23

中文print对齐

在中英文混合的过程中,经常令我们困惑的是\t起不到预期的作用,那我们怎么去处理他呢?

实际上中文的占位为全角,相对于英文的半角来说,通常会是两倍的长度。基于此,一种解决方案是计算出字符串中的中文数,将为中文预留的空格去掉,这样我们就可以做到print对齐了。

比如说,这样一句话:我爱hiphop,给定打印长度为20。直接计算的话会在这句话后面加上(20-len)=12个空格。而实际上,中文占用两个字符,我们需要把给中文的字符去掉,那么就是(20-len-len_ch)=10个空格。

注意:这个方案中需要预留足够的占位距离

以下为具体实现:

#coding=utf8
import re
lst1 = ["1up", "无政府主义者食谱"]
lst2 = ["额外生命", "召唤炸弹"]

def singleton(cls):
    instances = {}
    def getinstance():
        if cls not in instances:
            instances[cls] = cls()
        return instances[cls]
    return getinstance

@singleton
class ChineseDetected(object):
    _re = None

    def __init__(self):
        self._re = re.compile('[\u4e00-\u9fa5]+')

    def get_count(self, s):
        chinese_list = self._re.findall(s)
        count = 0
        for c_item in chinese_list:
            count += len(c_item)
        return count

def printItemList(ilt, ilt2):
    len_list = [5, 20, 35]
    fmt_template = "{:%d}\t{:%d}\t{:%d}"
    def make_fmt(idx):
        return fmt_template%(len_list[0], len_list[1]-cd.get_count(ilt[idx]), len_list[2] - cd.get_count(ilt2[idx]))
    cd = ChineseDetected()
    print((fmt_template%(len_list[0]-2,len_list[1]-2, len_list[2]-2)).format("序号", "物品", "功能"))
    count = 0
    for g in range(len(ilt2)):
        count += 1
        print(make_fmt(g).format(count, ilt[g], ilt2[g]))

printItemList(lst1, lst2)