python - 我该如何处理这些弄乱我的打印格式的奇怪特殊字符?

标签 python unicode terminal string-formatting python-unicode

我正在打印格式化表格。但有时这些用户生成的字符占用了不止一个字符宽度,它会弄乱格式,如下面的屏幕截图所示...

enter image description here

“标题”列的宽度被格式化为 68 字节。但是这些“特殊字符”占用了超过 1 个字符的宽度,但只算作 1 个字符。这会将列推到其边界之外。

print('{0:16s}{3:<18s}{1:68s}{2:>8n}'.format((
    ' ' + streamer['user_name'][:12] + '..') if len(streamer['user_name']) > 12 else ' ' + streamer['user_name'],
    (streamer['title'].strip()[:62] + '..') if len(streamer['title']) > 62 else streamer['title'].strip(),
    streamer['viewer_count'],
    (gamesDic[streamer['game_id']][:15] + '..') if len(gamesDic[streamer['game_id']]) > 15 else gamesDic[streamer['game_id']]))

关于如何处理这些特殊字符有什么建议吗?

编辑:我将有问题的字符串打印到文件中。

🔴 𝐀𝐒𝐌𝐑 (𝙪𝙥 𝙘𝙡𝙤𝙨𝙚) ✨ LIVE 🔔 SUBS GET SNAPCHAT

编辑2:

为什么这些不在字符边界上对齐?

enter image description here

编辑3:

今天前两个字符产生了奇怪的输出。但在下面的每种情况下,列都是对齐的。

孤立的第一个字符...

标题[0]

enter image description here

孤立的第二个字符... title[1]

enter image description here

第一个和第二个字符在一起.. title[0] + title[1]

first and second character

最佳答案

我对这个问题发表了评论:

The characters in "LIVE" are Fullwidth characters. A hacky way to deal with them might be to test their width with unicodedata.east_asian_width(char) (it will return "F" for fullwidth characters) and substitute with the final character of unicodedata.name(char) (or just count them as length 2)

这个“回答”本质上是另一个评论,但对于评论字段来说太长了。

这个 hack - 在 Alderven 的 answer 中实现- 几乎适用于 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 上的这条注释 standard建议:

Note: The East_Asian_Width property is not intended for use by modern terminal emulators without appropriate tailoring on a case-by-case basis. Such terminal emulators need a way to resolve the halfwidth/fullwidth dichotomy that is necessary for such environments, but the East_Asian_Width property does not provide an off-the-shelf solution for all situations. The growing repertoire of the Unicode Standard has long exceeded the bounds of East Asian legacy character encodings, and terminal emulations often need to be customized to support edge cases and for changes in typographical behavior over time.

关于python - 我该如何处理这些弄乱我的打印格式的奇怪特殊字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54821769/

相关文章:

python - 无法在 Ejabberd 19.09.1 中启动外部身份验证程序

python - 调试 SCons

c++ - 你用 VIM/Emacs/Terminals 开发 C/C++ 吗?这个实用的项目是什么?

javascript - 共享 linux 终端 - 解释分辨率差异

连接远程主机然后执行系统命令的C程序

python : While installing requirements dlib error showing on ubuntu 16. 04 网络服务器

python正则表达式重复组匹配

perl - IO::获取和取消获取 unicode 字符的句柄

java - 如何将字符串中的特殊字符转换为unicode?

php - 将命名的 HTML 实体转换为数字 HTML 实体