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

Zea*_*rin 9 python string terminal ansi-colors

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

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

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

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

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

帮助不大?☺

Mar*_*ers 6

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

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

您需要手动调整列对齐方式以允许使用这些额外字符。

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

  • 我发现对传递给已着色的字符串进行填充更容易。如果您没有背景颜色或不关心填充是否应用了背景颜色,则此方法有效。`stdout.write('{:s}\t [{:s}]\n'.format(x, colorize('{:^10}'.format(y), 'red'))` (3认同)

Jon*_*ice 6

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

byoungb关于对预着色文本的长度做出填充决定的评论是完全正确的.但如果您已经有彩色文本,这里有一个解决方法:

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

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

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

最新版本的ansicolors也包含一个等效的实现ansilen().