如何控制中英文混合时的输出格式?

4 投票
2 回答
2113 浏览
提问于 2025-04-18 04:26

我发现让文本对齐很困难。

table='''乘客姓名,性别,出生日期
HuangTianhui,男,1948/05/28
姜翠云,女,1952/03/27
李红晶,女,1994/12/09
LuiChing,女,1969/08/02
宋飞飞,男,1982/03/01
唐旭东,男,1983/08/03
YangJiabao,女,1988/08/25
买买提江·阿布拉,男,1979/07/10
安文兰,女,1949/10/20
胡偲婠(婴儿),女,2011/02/25
(有待确定姓名),男,1985/07/20
'''
data=[ [cell  for cell in row.split(",") ] for row in table.split("\n")  if row]
len0=max([ len(x[0])   for x in data])
len1=max([ len(x[1])   for x in data])
len2=max([ len(x[2])   for x in data])

for cell in data:
    print("_"*((len0+len1+len2)*2+4) )
    print("|%24s|%4s|%20s|" % (cell[0],cell[1],cell[2]))

在这里输入图片描述

并不是每一行的宽度都是(12+2+10)*2+4个字符,虽然使用了相同的格式控制语句,但输出却不同。我该怎么做才能让每一行的输出格式和宽度都一样呢?

2 个回答

7

你可以考虑字符串中全角字符和半角字符的数量:

#!/usr/bin/python3
# coding=utf8

import unicodedata

def wide_chars(s):
    return sum(unicodedata.east_asian_width(x)=='W' for x in s)
def width(s):
    return len(s) + wide_chars(s)

table='''乘客姓名,性别,出生日期
HuangTianhui,男,1948/05/28
姜翠云,女,1952/03/27
李红晶,女,1994/12/09
LuiChing,女,1969/08/02
宋飞飞,男,1982/03/01
唐旭东,男,1983/08/03
YangJiabao,女,1988/08/25
买买提江·阿布拉,男,1979/07/10
安文兰,女,1949/10/20
胡偲婠(婴儿),女,2011/02/25
(有待确定姓名),男,1985/07/20
'''
data=[ [cell  for cell in row.split(",") ] for row in table.split("\n")  if row]
len0=max([ width(x[0])   for x in data])
len1=max([ width(x[1])   for x in data])
len2=max([ width(x[2])   for x in data])

for cell in data:
    print("_"*((len0+len1+len2)*2+4) )
    print("|%*s|%*s|%*s|" % (24-wide_chars(cell[0]), cell[0],
                               4-wide_chars(cell[1]),cell[1],
                               20-wide_chars(cell[2]), cell[2]))

输出结果:

在这里输入图片描述

1

虽然不是很美观,但这是一种方法。(使用 bytes.rjust 来进行编码和解码)

table='''乘客姓名,性别,出生日期
HuangTianhui,男,1948/05/28
姜翠云,女,1952/03/27
李红晶,女,1994/12/09
LuiChing,女,1969/08/02
宋飞飞,男,1982/03/01
唐旭东,男,1983/08/03
YangJiabao,女,1988/08/25
提江·阿布拉,男,1979/07/10
安文兰,女,1949/10/20
胡偲婠(婴儿),女,2011/02/25
(有待确定姓名),男,1985/07/20
'''
table = table.encode('gb18030')
data = [[cell  for cell in row.split(b",")]
        for row in table.split(b"\n")  if row]
len0 = max([len(x[0]) for x in data])
len1 = max([len(x[1]) for x in data])
len2 = max([len(x[2]) for x in data])

for cell in data:
    print("_" * (len0+len1+len2+4))
    line = (
        b"|" + cell[0].rjust(len0) +
        b"|" + cell[1].rjust(len1) +
        b"|" + cell[2].rjust(len2) + b"|"
    )
    print(line.decode('gb18030'))

输出结果:

在这里输入图片描述

撰写回答