2 回答
TA贡献1826条经验 获得超6个赞
我对这个问题发表了以下评论:
“LIVE”中的字符为全角字符。一种处理它们的hacky方法可能是测试它们的宽度
unicodedata.east_asian_width(char)
(对于全角字符它将返回“F”)并替换为的最后一个字符unicodedata.name(char)
(或仅将它们计为长度2)
这个“答案”本质上是另一个评论,但对于评论字段来说太长了。
这个 hack - 在 Alderven 的回答中实现- 几乎适用于 OP,但示例字符串以额外的半个字符宽度呈现(注意示例字符串不包含任何东亚半角字符。)。
我无法使用此测试语句重现此确切行为,s
问题中的示例字符串在哪里,更改删除的字符:
print((s + (68 - (len(s) + sum(1 for x in s if ud.east_asian_width(x) in ('F', 'N', 'W')))) * 'x')+ '\n'+ ('x' * 68))
在 Debian 的 Gnome 终端中的 Python 3.6 解释器中,使用默认的等宽常规字体,删除全角字符会导致示例字符串明显比等效的 "x" 字符串长三个字符。
删除全角和宽(东亚宽度“W”)字符生成的字符串似乎呈现与等效数量的“x”相同的长度。
在 OpenSuse 上的 Python 3.7 KDE Konsole 终端中,使用 Ubuntu Monospace 常规字体,我无法生成呈现相同长度的字符串,无论我删除了全角、宽角或中性 (“N”) 字符的组合如何。
我确实注意到,在 Konsole 中单独渲染时,火花字符 (✨) 似乎占用了额外的半宽,但在测试完整字符串时看不到任何半宽差异。
我怀疑问题出在 Python 控制之外的低级渲染,正如关于 Unicode标准的这个注释所暗示的那样:
注意: East_Asian_Width 属性不适用于现代终端仿真器,而无需根据具体情况进行适当调整。此类终端仿真器需要一种方法来解决此类环境所需的半角/全角二分法,但 East_Asian_Width 属性并未为所有情况提供现成的解决方案。Unicode 标准不断增长的曲目早已超出了东亚传统字符编码的范围,终端仿真通常需要定制以支持边缘情况和随着时间的推移排版行为的变化。
TA贡献1772条经验 获得超6个赞
我已经根据@snakecharmerb 的评论编写了自定义字符串格式化程序,但仍然存在“半字符宽度”问题:
import unicodedata
def fstring(string, max_length, align='l'):
string = str(string)
extra_length = 0
for char in string:
if unicodedata.east_asian_width(char) == 'F':
extra_length += 1
diff = max_length - len(string) - extra_length
if diff > 0:
return string + diff * ' ' if align == 'l' else diff * ' ' + string
elif diff < 0:
return string[:max_length-3] + '.. '
return string
data = [{'user_name': 'shroud', 'game_id': 'Apex Legends', 'title': 'pathfinder twitch prime loot YAYA @shroud on socials for update', 'viewer_count': 66200},
{'user_name': 'Amouranth', 'game_id': 'ASMR', 'title': '🔴 𝐀𝐒𝐌𝐑 (𝙪𝙥 𝙘𝙡𝙤𝙨𝙚) ✨ LIVE 🔔 SUBS GET SNAPCHAT', 'viewer_count': 2261}]
for d in data:
name = fstring(d['user_name'], 20)
game_id = fstring(d['game_id'], 15)
title = fstring(d['title'], 62)
count = fstring(d['viewer_count'], 10, align='r')
print('{}{}{}{}'.format(name, game_id, title, count))
它产生输出:
添加回答
举报