Фильтрация управляющих последовательностей ANSI

У меня есть скрипт Python, который пытается интерпретировать трассировку данных, записанных и прочитанных из stdout и stdin соответственно. Проблема в том, что эти данные пронизаны побегами ANSI, которые меня не волнуют. Эти escape-последовательности закодированы в формате JSON, поэтому они выглядят как «\033[A» и «\033]0;». На самом деле мне не нужно интерпретировать коды, но мне нужно знать, сколько символов включено в каждый (вы заметите, что первая последовательность состоит из 6 символов, а вторая — из 7). Есть ли простой способ отфильтровать эти коды из строк, которые у меня есть?


person rivenmyst137    schedule 22.11.2012    source источник
comment
Программа colcrt уже делает это. Это не на Python, но если это необходимо, его можно портировать или обернуть.   -  person tripleee    schedule 22.11.2012


Ответы (5)


Полное регулярное выражение для управляющих последовательностей (также называемых управляющими последовательностями ANSI)

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

См. ECMA-48 Раздел 5.4 и Экран-код ANSI

person Jeff    schedule 25.11.2015
comment
не следует копировать ответы с одного вопроса на другой. - person Jean-François Fabre; 16.02.2019

Другой вариант:

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)
person boxed    schedule 03.04.2013

Это сработало для меня:

re.sub(r'\x1b\[[\d;]+m', '', s)
person Elliot Chance    schedule 21.03.2017

Это далеко не идеально, но это регулярное выражение может вам помочь:

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

Он уже правильно удаляет ваши два примера.

person BoppreH    schedule 22.11.2012

FWIW, это регулярное выражение Python, похоже, сработало для меня. Я на самом деле не знаю, точно ли это, но эмпирически это работает:

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