Python的`string.format()`,填充字符和ANSI颜色

时间:2013-01-03 14:23:17

标签: python string terminal ansi-colors

在Python 2中,我使用str.format()来对齐我正在打印的一堆文本列到终端。基本上,它是一个表,但我不打印任何边框或任何东西 - 它只是文本行,对齐成列。

  • 没有颜色摆弄,一切都按预期打印。
  • 如果我用ANSI颜色代码包装整行(即一个print语句),则所有内容都按预期打印。
  • 但是:如果我尝试在一行中使每列成为不同的颜色,则会抛弃对齐。从技术上讲,对齐被保留;它是未按要求打印的填充字符(空格);实际上,填充字符似乎已完全删除。

我已对coloramaxtermcolor验证了同样的问题。结果是一样的。因此,我确定该问题与str.format()在字符串中间不能很好地使用ANSI转义序列有关。

但我不知道该怎么办! :(我真的想知道这个问题是否有任何解决方法。

颜色和对齐是提高可读性的强大工具,可读性是软件可用性的重要组成部分。如果可以在不手动对齐每列文本的情况下完成此操作,对我来说意义重大。

帮助不大? ☺

2 个答案:

答案 0 :(得分:6)

这是一个非常晚的答案,对于那些在努力使用内置ANSI颜色代码格式化文本时找到此页面的人来说,面包屑会被丢弃。

byoungb's comment关于对预着色文本的长度做出填充决定是完全正确的。但如果您已经有彩色文字,那么这是一个解决方法:

在PyPI上查看我的ansiwrap模块。其主要目的是为ANSI颜色的文本提供textwrap,但它也会导出ansilen(),它会告诉您"如果没有那么这个字符串会有多长时间包含ANSI控制代码?"它对预先着色的文本进行格式化,列宽和包装决定非常有用。在所需width - ansilen(s)的列中,将s空格添加到s的左侧(或右侧)对齐width的末尾或开头。 E.g:

def ansi_ljust(s, width):
    needed = width - ansilen(s)
    if needed > 0:
        return s + ' ' * needed
    else:
        return s

此外,如果您需要在某些时候拆分,截断或组合彩色文本,您会发现ANSI的有状态性质使其成为一件苦差事。您可能会发现ansi_terminate_lines()有帮助;它"补丁"一个子字符串列表,以便每个子字符串具有独立的,独立的ANSI代码,其效果与原始字符串相同。

ansicolors的最新版本还包含ansilen()的等效实现。

答案 1 :(得分:4)

Python不区分“普通”字符和ANSI颜色代码,它们也是终端解释的字符。

换句话说,将'\x1b[92m'打印到终端可能会更改终端文本颜色,Python不会将其视为一组5个字符。如果改为使用print repr(line),python将打印字符串文字形式,包括使用非ASCII可打印字符的转义码(因此ESC ASCII代码27显示为\x1b)以查看许多已被添加。

您需要手动调整列对齐以容纳这些额外字符。

如果没有您的实际代码,我们很难为您提供帮助。