Python在字符串格式宽度字段中计算零长度控制字符?

时间:2015-07-26 22:53:20

标签: python terminal printf

在Python 3.4.3中,我尝试使用string.format()运算符对某些字段进行宽度对齐,并且它似乎根据宽度总计算零长控制字符。示例代码:

ANSI_RED = "\033[31m"
ANSI_DEFAULT="\033[39m\033[49m"

string1 = "12"
string2 = ANSI_RED+"12"+ANSI_DEFAULT

print("foo{:4s}bar".format(string1))
print("foo{:4s}bar".format(string2))

这将输出:

foo12  bar
foo12bar

(第二个输出的红色为“12”,但我无法在SO中重现)

在第二种情况下,我丢失了我的字段宽度,我假设因为Python看到字符串中的字符总数大于宽度,尽管大多数字符在ANSI上导致零长度符合终端。

使用ANSI颜色和工作区域宽度的干净方法是什么?

3 个答案:

答案 0 :(得分:1)

  

具有ANSI颜色和工作区域宽度的干净方法是什么?

不幸的是,您必须剥离转义序列以获得显示的字段宽度。

len()函数返回Python 2 str类型中的字节数和Python 3 str类型中的代码点数。从未保证该长度与显示宽度相匹配(这是一个更具挑战性的问题):

>>> s = 'abc\bde'
>>> print s
abcde
>>> len(s)
6

一般情况下,您无法确定显示宽度,除非您了解显示器将如何解释代码(即宽度因设备是否支持ANSI转义序列而有所不同)。

答案 1 :(得分:1)

我不知道它是否符合“干净”的条件,但是下面的事情是徒劳的:

print("foo{0}{1:4s}{2}bar".format(ANSI_RED, string1, ANSI_DEFAULT))

答案 2 :(得分:1)

正确获取终端控制代码非常困难(如下所示,并非所有这些代码都具有明确定义的宽度),因此最好的选择可能是使用明确的列移动。

# string2 defined as above
def col(n): return "\033[{:d}G".format(n)
print("foo{:s}{:s}bar".format(string2,col(8)))

输出:

foo12  bar