Mam skrypt w języku Pythona, który próbuje interpretować ślad danych zapisanych i odczytanych odpowiednio z stdout i stdin. Problem polega na tym, że te dane są przesiąknięte ucieczkami ANSI, o które nie dbam. Te wartości są kodowane JSON, więc wyglądają jak "\ 033 [A" i "\ 033] 0;". Właściwie nie potrzebuję interpretować kodów, ale muszę wiedzieć, ile znaków znajduje się w każdym z nich (zauważysz, że pierwsza sekwencja składa się z 6 znaków, a druga z 7). Czy istnieje prosty sposób odfiltrowania tych kodów z ciągów, które mam?Filtrowanie sekwencji escape ANSI
5
A
Odpowiedz
0
To dalekie od doskonałości, ale regex może Ci somwhere:
import re
text = r'begin \033[A middle \033]0; end'
print re.sub(r'\\[0-9]+(\[|\])[0-9]*;?[A-Z]?', '', text)
już usuwa swoje dwa przykłady poprawnie.
0
FWIW, to Python regex wydawało się działać dla mnie. I właściwie nie wiem, czy to prawdziwe, ale empirycznie wydaje się działać:
r'\\033[\[\]]([0-9]{1,2}([;@][0-9]{0,2})*)*[mKP]?'
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
6
Inny wariant:
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)
7
Kompletny regexp dla sekwencji kontrolnych (aka ANSI Sekwencje) jest
/(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]/
Patrz ECMA-48 Section 5.4 i ANSI escape code
1
Ten pracował dla mnie:
re.sub(r'\x1b\[[\d;]+m', '', s)
Powiązane problemy
- 1. Jak przechwycić tytuł okna terminala w bashu używając sekwencji kontrolnych ANSI?
- 2. Jak korzystać z nowej obsługi sekwencji kontrolnych ANSI w konsoli systemu Windows 10?
- 3. Jak załadować kody escape ANSI lub uzyskać kolorowy plik w powłoce cmd WinXP?
- 4. Analizować kolory kodów ewidencyjnych ANSI w przeglądarce?
- 5. Jak używać sekwencji escape w pytaniu ZSH dla truecolor lub pogrubienia?
- 6. Czy "ANSI C" lub "ANSI C++" nadal coś znaczą?
- 7. „Stałe ANSI” Java
- 8. ANSI SQL Manual
- 9. Jak wstawić znak escape (NIE "escaped" znak) w regex Ruby?
- 10. Escape pipe-character w trybie org.
- 11. angular translate sanitize/escape
- 12. Doctest Involving Escape Characters
- 13. Escape Regex Newline
- 14. Escape a string
- 15. Autouzupełnianie IntelliJ escape
- 16. Escape `@` w szablonach yesod
- 17. Naprawianie nieprawidłowego JSON escape
- 18. Escape + (plus) w URI
- 19. CURL escape single quote
- 20. Escape NSDateFormatter String
- 21. Konwersja sekwencji sekwencji do słownika i odwrotnie
- 22. Wykryj konsolę zgodną z ANSI z pliku wsadowego Windows?
- 23. Filtrowanie Logcat?
- 24. Backbone filtrowanie
- 25. Filtrowanie Wienera
- 26. Rozdzielanie sekwencji heksadecymalnych w łańcuchach znaków
- 27. Josephus sekwencji
- 28. ANSI C odpowiednik try/catch?
- 29. Kolorowanie ANSI w trybie kompilacji
- 30. ANSI Colour Codes w vim
Opcja 'Program colcrt' już to robi. Nie jest to w Pythonie, ale jeśli jest to wymagane, może być przeniesione lub opakowane. – tripleee