Регулярное выражение Python для соответствия escape-последовательностей VT100
Я пишу программу на Python, которая регистрирует взаимодействие с терминалом (по аналогии со скриптовой программой), и я хотел бы отфильтровать escape-последовательности VT100 перед записью на диск. Я хотел бы использовать такую функцию:
def strip_escapes(buf):
escape_regex = re.compile(???) # <--- this is what I'm looking for
return escape_regex.sub('', buf)
Что должно идти в escape_regex
?
3 ответа
Комбинированное выражение для escape-последовательностей может быть чем-то общим:
(\x1b\[|\x9b)[^@-_]*[@-_]|\x1b[@-_]
Должен использоваться сre.I
Это включает в себя:
- Двухбайтовые последовательности, т.е.
\x1b
сопровождаемый символом в диапазоне@
до тех пор_
, - Однобайтовая CSI, т.е.
\x9b
в отличие от\x1b + "["
,
Однако это не будет работать для последовательностей, которые определяют сопоставления клавиш или иным образом включенные строки, заключенные в кавычки.
Коды VT100 уже сгруппированы (в основном) по схожим схемам здесь:
http://ascii-table.com/ansi-escape-sequences-vt-100.php
Я думаю, что самым простым подходом было бы использование некоторого инструмента, такого как regexbuddy, для определения регулярного выражения для каждой группы кодов VT100.
Я нашел следующее решение для успешного анализа цветовых кодов vt100 и удаления непечатаемых escape-последовательностей. Найденный здесь фрагмент кода успешно удалил все коды для меня при запуске сеанса telnet с использованием telnetlib:
def __processReadLine(self, line_p):
'''
remove non-printable characters from line <line_p>
return a printable string.
'''
line, i, imax = '', 0, len(line_p)
while i < imax:
ac = ord(line_p[i])
if (32<=ac<127) or ac in (9,10): # printable, \t, \n
line += line_p[i]
elif ac == 27: # remove coded sequences
i += 1
while i<imax and line_p[i].lower() not in 'abcdhsujkm':
i += 1
elif ac == 8 or (ac==13 and line and line[-1] == ' '): # backspace or EOL spacing
if line:
line = line[:-1]
i += 1
return line