过滤ANSI转义序列

时间:2012-11-22 04:43:40

标签: python ansi-escape

我有一个python脚本试图解释分别写入和读取stdout和stdin的数据跟踪。问题是这个数据充满了我不关心的ANSI转义。这些转义符是JSON编码的,因此它们看起来像“\ 033 [A”和“\ 033] 0;”。我实际上不需要解释代码,但我确实需要知道每个代码中包含多少个字符(您会注意到第一个序列是6个字符,而第二个序列是7个字符)。有没有一种直接的方法从我拥有的字符串中过滤掉这些代码?

6 个答案:

答案 0 :(得分:9)

控制序列(又名ANSI转义序列)的完整正则表达式是

/(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]/

请参阅ECMA-48 Section 5.4ANSI escape code

答案 1 :(得分:7)

另一种变体:

def strip_ansi_codes(s):
    """
    >>> import blessings
    >>> term = blessings.Terminal()
    >>> foo = 'hidden'+term.clear_bol+'foo'+term.color(5)+'bar'+term.color(255)+'baz'
    >>> repr(strip_ansi_codes(foo))
    u'hiddenfoobarbaz'
    """
    return re.sub(r'\x1b\[([0-9,A-Z]{1,2}(;[0-9]{1,2})?(;[0-9]{3})?)?[m|K]?', '', s)

答案 2 :(得分:1)

#!/usr/bin/env python
import re

ansi_pattern = '\033\[((?:\d|;)*)([a-zA-Z])'
ansi_eng = re.compile(ansi_pattern)

def strip_escape(string=''):
    lastend = 0
    matches = []
    newstring = str(string)
    for match in ansi_eng.finditer(string):
        start = match.start()
        end = match.end()
        matches.append(match)
    matches.reverse()
    for match in matches:
        start = match.start()
        end = match.end()
        string = string[0:start] + string[end:]
    return string

if __name__ == '__main__':
    import sys
    import os

    lname = sys.argv[-1]
    fname = os.path.basename(__file__)
    if lname != fname:
        with open(lname, 'r') as fd:
            for line in fd.readlines():
                print strip_escape(line).rstrip()
    else:
        USAGE = '%s <filename>' % fname
        print USAGE

答案 3 :(得分:1)

这对我有用:

re.sub(r'\x1b\[[\d;]+m', '', s)

答案 4 :(得分:0)

这远非完美,但这个正则表达式可能会让你到达某个地方:

import re
text = r'begin \033[A middle \033]0; end'
print re.sub(r'\\[0-9]+(\[|\])[0-9]*;?[A-Z]?', '', text)

它已经正确删除了你的两个例子。

答案 5 :(得分:0)

FWIW,这个Python正则表达式似乎对我有用。我实际上并不知道它是否准确,但凭经验它似乎有效:

r'\\033[\[\]]([0-9]{1,2}([;@][0-9]{0,2})*)*[mKP]?'