Python utf-8,如何对齐输出
我有一个数组,里面包含了日文字符和“普通”的字符。请问我该如何让它们的输出对齐呢?
#!/usr/bin/python
# coding=utf-8
a1=['する', 'します', 'trazan', 'した', 'しました']
a2=['dipsy', 'laa-laa', 'banarne', 'po', 'tinky winky']
for i,j in zip(a1,a2):
print i.ljust(12),':',j
print '-'*8
for i,j in zip(a1,a2):
print i,len(i)
print j,len(j)
输出:
する : dipsy
します : laa-laa
trazan : banarne
した : po
しました : tinky winky
--------
する 6
dipsy 5
します 9
laa-laa 7
trazan 6
banarne 7
した 6
po 2
しました 12
tinky winky 11
谢谢,
//Fredrik
3 个回答
1
你需要手动构建字符串,并且还要手动计算格式长度。这个过程没有简单的方法。
下面这三个函数可以帮你完成这个任务(需要用到unicodedata库):
shortenStringCJK:这个函数可以正确地将字符串缩短到适合某些输出的长度(不是简单地截取X个字符)。
def shortenStringCJK(string, width, placeholder='..'):
# get the length with double byte charactes
string_len_cjk = stringLenCJK(str(string))
# if double byte width is too big
if string_len_cjk > width:
# set current length and output string
cur_len = 0
out_string = ''
# loop through each character
for char in str(string):
# set the current length if we add the character
cur_len += 2 if unicodedata.east_asian_width(char) in "WF" else 1
# if the new length is smaller than the output length to shorten too add the char
if cur_len <= (width - len(placeholder)):
out_string += char
# return string with new width and placeholder
return "{}{}".format(out_string, placeholder)
else:
return str(string)
stringLenCJK:这个函数可以获取字符串的正确长度(就像在终端上占用的空间一样)。
def stringLenCJK(string):
# return string len including double count for double width characters
return sum(1 + (unicodedata.east_asian_width(c) in "WF") for c in string)
formatLen:这个函数用于调整长度,以适应双字节字符的宽度。如果没有这个函数,长度会不平衡。
def formatLen(string, length):
# returns length udpated for string with double byte characters
# get string length normal, get string length including double byte characters
# then subtract that from the original length
return length - (stringLenCJK(string) - len(string))
然后要输出某个字符串时:提前定义格式字符串。
format_str = "|{{:<{len}}}|"
format_len = 26
string_len = 26
最后按如下方式输出(其中_string是要输出的字符串)。
print("Normal : {}".format(
format_str.format(
len=formatLen(shortenStringCJK(_string, width=string_len), format_len))
).format(
shortenStringCJK(_string, width=string_len)
)
)
2
使用Unicode对象,而不是字节字符串:
#!/usr/bin/python
# coding=utf-8
a1=[u'する', u'します', u'trazan', u'した', u'しました']
a2=[u'dipsy', u'laa-laa', u'banarne', u'po', u'tinky winky']
for i,j in zip(a1,a2):
print i.ljust(12),':',j
print '-'*8
for i,j in zip(a1,a2):
print i,len(i)
print j,len(j)
Unicode对象直接处理字符。
6
使用 unicodedata.east_asian_width
这个函数,可以在计算字符串长度的时候,记录哪些字符是窄的,哪些是宽的。
#!/usr/bin/python
# coding=utf-8
import sys
import codecs
import unicodedata
out = codecs.getwriter('utf-8')(sys.stdout)
def width(string):
return sum(1+(unicodedata.east_asian_width(c) in "WF")
for c in string)
a1=[u'する', u'します', u'trazan', u'した', u'しました']
a2=[u'dipsy', u'laa-laa', u'banarne', u'po', u'tinky winky']
for i,j in zip(a1,a2):
out.write('%s %s: %s\n' % (i, ' '*(12-width(i)), j))
输出结果:
する : dipsy
します : laa-laa
trazan : banarne
した : po
しました : tinky winky
在某些网页浏览器的字体中看起来不太对,但在终端窗口中它们的对齐是正确的。