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

Posted

技术标签:

【中文标题】Python `string.format()`、填充字符和 ANSI 颜色【英文标题】:Python’s `str.format()`, fill characters, and ANSI colors 【发布时间】:2012-12-17 22:11:03 【问题描述】:

在 Python 2 中,我使用 str.format() 将我打印到终端的一堆文本列对齐。基本上,它是一张表格,但我没有打印任何边框或任何东西——它只是文本行,对齐到列中。

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

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

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

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

帮助不大? ☺

【问题讨论】:

如果您想要的不仅仅是“Python .format() 不会对 ANSI 转义字符有任何不同”,您需要向我们展示您的(部分)代码。 我知道在没有代码本身的情况下提供帮助会比较棘手。对于那个很抱歉。不过,我希望得到像下面发布的@MartijnPieters 这样的答案。如果我没有任何运气,我会继续发布代码。 另见***.com/questions/2186919/… 【参考方案1】:

这是一个很晚的答案,对于在努力使用内置 ANSI 颜色代码格式化文本的同时找到此页面的任何人来说都是面包屑。

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

在 PyPI 上查看我的 ansiwrap 模块。它的主要目的是为 ANSI 彩色文本提供 textwrap,但它也导出 ansilen(),告诉您“如果它包含 ANSI 控制代码,这个字符串会有多长时间?”它在对预着色文本进行格式设置、列宽和换行决策方面非常有用。将width - ansilen(s) 空格添加到s 的末尾或开头向左(或分别为右)在所需width 的列中对齐s。例如:

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() 的等效实现。

【讨论】:

感谢您提供的 ansiwrap 模块!对于任何像我一样努力使用漂亮的终端着色的人,编辑 prettytable.py 并将 import textwrap 替换为 import ansiwrap as textwrap【参考方案2】:

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'))

以上是关于Python `string.format()`、填充字符和 ANSI 颜色的主要内容,如果未能解决你的问题,请参考以下文章

hausaufgabe--python 15- String Format

理解字符串格式化中的 Python %g,实现 Java String.format 行为

带有可选占位符的 string.format()

Python 里的 String format问题, 我搞不懂这个东西到底是怎么用的。

如何在 C# 中将“”添加到 string.Format [重复]

python 字符串常用函数