2011-10-22 6 views
9

Sto scrivendo un programma Python che registra l'interazione del terminale (simile al programma script) e mi piacerebbe filtrare le sequenze di escape VT100 prima di scrivere su disco. Mi piacerebbe usare una funzione come questa:Python regex per abbinare sequenze di escape VT100

def strip_escapes(buf): 
    escape_regex = re.compile(???) # <--- this is what I'm looking for 
    return escape_regex.sub('', buf) 

cosa dovrebbe andare in escape_regex?

+0

E 'un po' complicato: http://en.wikipedia.org/wiki/ANSI_escape_sequences – sarnold

+2

Controllare http: // www .webdeveloper.com/forum/showthread.php? t = 186004 per una versione PHP. Dovrebbe essere semplice convertirlo in python. – Mansour

+1

Nello spirito di questi altri commenti, ecco anche un processo TCL che fa esattamente la stessa cosa ... http://wiki.tcl.tk/9673 –

risposta

2

codici VT100 sono già raggruppate (principalmente) secondo schemi analoghi qui:

http://ascii-table.com/ansi-escape-sequences-vt-100.php

ritengo l'approccio più semplice sarebbe quella di utilizzare qualche strumento come RegexBuddy per definire una regex per ciascun gruppo di codici VT100.

4

L'espressione combinato per le sequenze di escape può essere qualcosa generico come questo:

(\x1b\[|\x9b)[^@-_]*[@-_]|\x1b[@-_] 

deve essere usato con re.I

Questo comprende:

  1. sequenze a due byte, vale a dire \x1b seguito da un carattere nell'intervallo @ fino a _ .
  2. CSI a un byte, ad esempio \x9b in contrasto con \x1b + "[".

Tuttavia, questo non funzionerà per le sequenze che definiscono mappature dei tasti o altrimenti incluse stringhe racchiuse tra virgolette.

1

Ho trovato la seguente soluzione per analizzare correttamente i codici colore vt100 e rimuovere le sequenze di escape non stampabili. Il frammento di codice trovato here rimosso con successo tutti i codici per me durante l'esecuzione di una sessione telnet utilizzando 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 
+0

Che non funzionerà per alcune sequenze di inizializzazione comuni, come ad esempio escape = escape> escape 7 escape 8 così come qualsiasi controllo * reset mode * (termina con "l"). Questi sono elencati nella documentazione di xterm: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html –