一、综述
py3中str的len是计算字符数量,例如len(‘ab’) --> 2, len(‘a中b’) --> 3。
但在对齐等操作中,是需要将每个汉字当成宽度2来处理,计算字符串实际宽度的。
所以我们需要开发一个strwidth函数,效果: strwidth(‘ab’) --> 2,strwidth(‘a中b’) --> 4。
结论及推荐字符串域宽计算方法为:
def strwidth(s):
"""string width
中英字符串实际宽度
>>> strwidth('ab')
2
>>> strwidth('a⑪中⑩')
7
"""
try:
res = len(s.encode('gbk'))
except UnicodeEncodeError:
count = len(s)
for x in s:
if ord(x) > 127:
count += 1
res = count
return res
然后实现关键函数listalign用于处理某一列的对齐:
from align import listalign
ls = ['22', '哈哈', '中_文a']
print(*listalign(ls), sep='\n')
# 22
# 哈哈
# 中_文a
再利用listalign实现一个对齐二维数组的函数arralign:
from align import arralign
ls = [
[1, '22', 'c'],
[123, 4, '哈哈', 'cde'],
[1, '中_文a', 'dd']
]
print(arralign(ls))
# print(arralign(ls, chinese_char_width=1.8)),本篇文章为了显示对齐,要用汉字域宽1.8的参数
# 1 22 c
# 123 4 哈哈 cde
# 1 中_文a dd
完整代码: align.py。
二、实现方法分析
百度一下能找到一些方法资料,我们来研究(TiGuan)一下。
2.1 使用中文空格chr(12288)
沧海漂游_,Python 中英文混输格式对齐问题,优快云,2017.8
这篇原理是对只有中文的字符串,填充的时候用域宽也是2的中文空格“chr(12288)”代替域宽为1的英文空格,从而实现只有中文的某一列的对齐效果。但这样遇到中英文混合字符串,例如把“清华大学”改成’a清华大学b’,就对不齐了。
2.2 字符集分类处理
mozaibin,python 中英文混合格式化输出对齐,鱼C论坛,2018.4
mozaibin应该是对编码做分类计算,感觉搞复杂了,而且算一个“⑩”就出错了,算出来是1,实际上是2。