sacar - ¿Cómo puedo eliminar las secuencias de escape ANSI de una cadena en python?
quitar de una cadena python (5)
Función
Basado en la respuesta de Martijn Pieters ♦ con la expresión regular de Jeff .
def escape_ansi(line):
ansi_escape = re.compile(r''(/x9B|/x1B/[)[0-?]*[ -/]*[@-~]'')
return ansi_escape.sub('''', line)
Prueba
def test_remove_ansi_escape_sequence(self):
line = ''/t/u001b[0;35mBlabla/u001b[0m /u001b[0;36m172.18.0.2/u001b[0m''
escaped_line = escape_ansi(line)
self.assertEqual(escaped_line, ''/tBlabla 172.18.0.2'')
Pruebas
Si desea ejecutarlo usted mismo, use python3
(mejor soporte Unicode, blablabla). Aquí es cómo debería ser el archivo de prueba:
import unittest
import re
def escape_ansi(line):
…
class TestStringMethods(unittest.TestCase):
def test_remove_ansi_escape_sequence(self):
…
if __name__ == ''__main__'':
unittest.main()
Esta es mi cadena:
''ls/r/n/x1b[00m/x1b[01;31mexamplefile.zip/x1b[00m/r/n/x1b[01;31m''
Estaba usando el código para recuperar el resultado de un comando SSH y quiero que mi cadena solo contenga ''examplefile.zip''
¿Qué puedo usar para eliminar las secuencias de escape adicionales?
Eliminarlos con una expresión regular:
import re
ansi_escape = re.compile(r''/x1B/[[0-?]*[ -/]*[@-~]'')
ansi_escape.sub('''', sometext)
Manifestación:
>>> import re
>>> ansi_escape = re.compile(r''/x1B/[[0-?]*[ -/]*[@-~]'')
>>> sometext = ''ls/r/n/x1b[00m/x1b[01;31mexamplefile.zip/x1b[00m/r/n/x1b[01;31m''
>>> ansi_escape.sub('''', sometext)
''ls/r/nexamplefile.zip/r/n''
(He ordenado la expresión de la secuencia de escape para seguir la descripción general de Wikipedia de los códigos de escape ANSI , centrándome en las secuencias CSI e ignorando los códigos C1, ya que nunca se utilizan en el mundo UTF-8 actual).
La expresión regular sugerida no me gustó, así que creé una propia. La siguiente es una expresión regular de python que creé en base a la especificación que se encuentra here
ansi_regex = r''/x1b('' /
r''(/[/??/d+[hl])|'' /
r''([=<>a-kzNM78])|'' /
r''([/(/)][a-b0-2])|'' /
r''(/[/d{0,2}[ma-dgkjqi])|'' /
r''(/[/d+;/d+[hfy]?)|'' /
r''(/[;?[hf])|'' /
r''(#[3-68])|'' /
r''([01356]n)|'' /
r''(O[mlnp-z]?)|'' /
r''(/Z)|'' /
r''(/d+)|'' /
r''(/[/?/d;/d0c)|'' /
r''(/d;/dR))''
ansi_escape = re.compile(ansi_regex, flags=re.IGNORECASE)
Probé mi expresión regular en el siguiente fragmento (básicamente, un copiar y pegar de la página de asciitable).
/x1b[20h Set
/x1b[?1h Set
/x1b[?3h Set
/x1b[?4h Set
/x1b[?5h Set
/x1b[?6h Set
/x1b[?7h Set
/x1b[?8h Set
/x1b[?9h Set
/x1b[20l Set
/x1b[?1l Set
/x1b[?2l Set
/x1b[?3l Set
/x1b[?4l Set
/x1b[?5l Set
/x1b[?6l Set
/x1b[?7l Reset
/x1b[?8l Reset
/x1b[?9l Reset
/x1b= Set
/x1b> Set
/x1b(A Set
/x1b)A Set
/x1b(B Set
/x1b)B Set
/x1b(0 Set
/x1b)0 Set
/x1b(1 Set
/x1b)1 Set
/x1b(2 Set
/x1b)2 Set
/x1bN Set
/x1bO Set
/x1b[m Turn
/x1b[0m Turn
/x1b[1m Turn
/x1b[2m Turn
/x1b[4m Turn
/x1b[5m Turn
/x1b[7m Turn
/x1b[8m Turn
/x1b[1;2 Set
/x1b[1A Move
/x1b[2B Move
/x1b[3C Move
/x1b[4D Move
/x1b[H Move
/x1b[;H Move
/x1b[4;3H Move
/x1b[f Move
/x1b[;f Move
/x1b[1;2 Move
/x1bD Move/scroll
/x1bM Move/scroll
/x1bE Move
/x1b7 Save
/x1b8 Restore
/x1bH Set
/x1b[g Clear
/x1b[0g Clear
/x1b[3g Clear
/x1b#3 Double-height
/x1b#4 Double-height
/x1b#5 Single
/x1b#6 Double
/x1b[K Clear
/x1b[0K Clear
/x1b[1K Clear
/x1b[2K Clear
/x1b[J Clear
/x1b[0J Clear
/x1b[1J Clear
/x1b[2J Clear
/x1b5n Device
/x1b0n Response:
/x1b3n Response:
/x1b6n Get
/x1b[c Identify
/x1b[0c Identify
/x1b[?1;20c Response:
/x1bc Reset
/x1b#8 Screen
/x1b[2;1y Confidence
/x1b[2;2y Confidence
/x1b[2;9y Repeat
/x1b[2;10y Repeat
/x1b[0q Turn
/x1b[1q Turn
/x1b[2q Turn
/x1b[3q Turn
/x1b[4q Turn
/x1b< Enter/exit
/x1b= Enter
/x1b> Exit
/x1bF Use
/x1bG Use
/x1bA Move
/x1bB Move
/x1bC Move
/x1bD Move
/x1bH Move
/x1b12 Move
/x1bI
/x1bK
/x1bJ
/x1bZ
/x1b/Z
/x1bOP
/x1bOQ
/x1bOR
/x1bOS
/x1bA
/x1bB
/x1bC
/x1bD
/x1bOp
/x1bOq
/x1bOr
/x1bOs
/x1bOt
/x1bOu
/x1bOv
/x1bOw
/x1bOx
/x1bOy
/x1bOm
/x1bOl
/x1bOn
/x1bOM
/x1b[i
/x1b[1i
/x1b[4i
/x1b[5i
Espero que esto ayude a otros :)
La respuesta aceptada a esta pregunta solo considera el color y los efectos de fuente. Hay muchas secuencias que no terminan en ''m'', como el posicionamiento del cursor, el borrado y las regiones de desplazamiento.
La expresión regular completa para Secuencias de control (también conocida como Secuencias de escape ANSI) es
/(/x9B|/x1B/[)[0-?]*[ -//]*[@-~]/
Consulte la Sección 5.4 de ECMA-48 y el código de escape de ANSI
si desea eliminar el bit /r/n
, puede pasar la cadena a través de esta función ( escrita por sarnold ):
def stripEscape(string):
""" Removes all escape sequences from the input string """
delete = ""
i=1
while (i<0x20):
delete += chr(i)
i += 1
t = string.translate(None, delete)
return t
Sin embargo, cuidado, esto juntará el texto delante y detrás de las secuencias de escape. Entonces, usando la cadena filtrada de Martijn ''ls/r/nexamplefile.zip/r/n''
, obtendrás lsexamplefile.zip
. Tenga en cuenta el ls
en frente del nombre de archivo deseado.
Primero usaría la función stripEscape para eliminar las secuencias de escape, luego pasaría la salida a la expresión regular de Martijn, lo que evitaría concatenar el bit no deseado.