在 Python 中获取具有 ANSI 颜色代码的字符串的正确字符串长度
我有一些 Python 代码,可以自动以良好的列格式打印一组数据,包括放入适当的 ASCII 转义序列来为数据的各个部分着色以提高可读性。
我最终将每一行表示为一个列表,每个项目都是一个用空格填充的列,以便每行上的相同列始终具有相同的长度。不幸的是,当我真正去打印这个时,并不是所有的列都对齐。我怀疑这与 ASCII 转义序列有关 - 因为 len
函数似乎无法识别这些:
>>> a = '\x1b[1m0.0\x1b[0m'
>>> len(a)
11
>>> print a
0.0
因此,虽然根据 len
每列的长度相同,当打印在屏幕上时,它们的长度实际上并不相同。
有没有什么方法(除了用正则表达式做一些我不想做的黑客行为之外)来获取转义字符串并找出打印的长度,以便我可以适当地填充空格?也许有某种方法可以将其“打印”回字符串并检查其长度?
I've got some Python code that will automatically print a set of data in a nice column format, including putting in the appropriate ASCII escape sequences to color various pieces of the data for readability.
I eventually end up with each line being represented as a list, with each item being a column that is space-padded so that the same columns on each line are always the same length. Unfortunately when I actually go to print this, not all the columns line up. I suspect this is to do with the ASCII escape sequences - because the len
function doesn't seem to recognize these:
>>> a = '\x1b[1m0.0\x1b[0m'
>>> len(a)
11
>>> print a
0.0
And so while each column is the same length according to len
, they are not actually the same length when printed on the screen.
Is there any way (save for doing some hackery with regular expressions which I'd rather not do) to take the escaped string and find out what the printed length is so I can space pad appropriately? Maybe some way to just "print" it back to string and examine the length of that?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
pyparsing wiki 包含这个有用的表达式,用于匹配 ANSI 转义序列:
以下是如何将其变成转义序列剥离器:
打印:
The pyparsing wiki includes this helpful expression for matching on ANSI escape sequences:
Here's how to make this into an escape-sequence-stripper:
prints:
我不明白两件事。
(1) 这是您的代码,由您控制。您想向数据添加转义序列,然后再次将其删除,以便可以计算数据的长度?在添加转义序列之前计算填充似乎要简单得多。我缺少什么?
我们假设没有任何转义序列改变光标位置。如果他们这样做,当前接受的答案无论如何都不会起作用。
假设您在名为
string_data
的列表中拥有每列的字符串数据(在添加转义序列之前),并且预先确定的列宽度位于名为width
的列表中。尝试这样的事情:Update-1
OP 评论后:
如果数据由各个部分组成,每个部分都有自己的格式,您仍然可以根据需要计算显示的长度和填充。这是一个对一个单元格的内容执行此操作的函数:
如果您认为标点符号使调用负担过重,您可以执行以下操作:
(2) 我不明白为什么您不想这样做使用Python提供的正则表达式工具包?不涉及“黑客”(对于我所知道的“黑客”的任何可能含义):
Update-2
OP评论后:
比什么更简洁?以下正则表达式解决方案对您来说还不够简洁吗?
[以上代码在 @Nick Perkins 指出它不起作用后已更正]
I don't understand TWO things.
(1) It is your code, under your control. You want to add escape sequences to your data and then strip them out again so that you can calculate the length of your data?? It seems much simpler to calculate the padding before adding the escape sequences. What am I missing?
Let's presume that none of the escape sequences change the cursor position. If they do, the currently accepted answer won't work anyway.
Let's assume that you have the string data for each column (before adding escape sequences) in a list named
string_data
and the pre-determined column widths are in a list namedwidth
. Try something like this:Update-1
After OP's comment:
If the data is built up of pieces each with its own formatting, you can still compute the displayed length and pad as appropriate. Here's a function which does that for one cell's contents:
If you think that the call is overburdened by punctuation, you could do something like:
(2) I don't understand why you don't want to use the supplied-with-Python regular expression kit? No "hackery" (for any possible meaning of "hackery" that I'm aware of) is involved:
Update-2
After OP's comment:
More concise than what? Isn't the following regex solution concise enough for you?
[Above code corrected after @Nick Perkins pointed out that it didn't work]
查看ANSI_escape_code,示例中的序列是
选择图形呈现(可能是粗体)。
尝试使用 CUrsor Position (
CSI n ; m H
) 序列控制列定位。这样,前面文本的宽度不会影响当前列位置,并且无需担心字符串宽度。
如果您的目标是 Unix,更好的选择是使用 curses 模块 window-objects< /a>.
例如,可以使用以下命令将字符串定位在屏幕上:
Looking in ANSI_escape_code, the sequence in your example is
Select Graphic Rendition (probably bold).
Try to control column positioning with the CUrsor Position (
CSI n ; m H
) sequence.This way, width of preceding text does not affect current column position and there is no need to worry about string widths.
A better option, if you target Unix, is using the curses module window-objects.
For example, a string can be positioned on the screen with:
如果您只是向某些单元格添加颜色,则可以将 9 添加到预期的单元格宽度(5 个隐藏字符用于打开颜色,4 个用于关闭颜色),例如
给出
If you're just adding color to some cells, you can add 9 to the expected cell width (5 hidden characters to turn on the color, 4 to turn it off), e.g.
Giving