2013-02-15 4 views
6

Gibt es eine Möglichkeit, die Länge einer Zeichenfolge in Python zu finden (auch eine beste Schätzung)? Z.B. 'potaa \ bto' ist 8 Zeichen in len, aber nur 6 Zeichen breit auf einem tty gedruckt.Gedruckte Länge einer Zeichenfolge in Python

Erwartete Nutzung:

s = 'potato\x1b[01;32mpotato\x1b[0;0mpotato' 
len(s) # 32 
plen(s) # 18 
+0

Nevermind, ich falsch verstanden die questiom –

+1

Was ist '' plen' von "abc" '? Wie wäre es mit '" 123 \ t456 "'? "12345 \ r67" '? '" 123456 \ n789 "'? '" 123456 \ r78 \ n9abcd "'? Im Wesentlichen müssen Sie sich für die Regeln für Ihren Zeichensatz entscheiden und einen Algorithmus schreiben. –

+1

Das ist wirklich schwer. Ich habe versucht verschiedene Ansätze, einschließlich einiger 'subprocess.Popen (...). Communicate()' versucht, aber ohne Erfolg. –

Antwort

1

Zumindest für die ANSI TTY-Escape-Sequenz, das funktioniert:

import re 
strip_ANSI_pat = re.compile(r""" 
    \x1b  # literal ESC 
    \[  # literal [ 
    [;\d]* # zero or more digits or semicolons 
    [A-Za-z] # a letter 
    """, re.VERBOSE).sub 

def strip_ANSI(s): 
    return strip_ANSI_pat("", s) 

s = 'potato\x1b[01;32mpotato\x1b[0;0mpotato' 

print s, len(s) 
s1=strip_ANSI(s) 
print s1, len(s1) 

Drucke:

potato[01;32mpotato[0;0mpotato 32 
potatopotatopotato 18 

Für Backspaces \ b oder vertikal Tabs oder \ r vs \ n - es hängt davon ab, wie und wo es gedruckt wird, nein?

+0

Ich suche nach einer allgemeineren Lösung ... es gibt viele andere nicht druckbare Zeichen als in meinem Beispiel. Ja, es hängt davon ab, wie und wo, ich denke ... das ist nur für hübsche Druck/Tabellierung, so dass es nicht zu drastisch ist, wenn es ihnen manchmal falsch geht – wim

+0

Sie könnten in [curses] waten (http://docs.python.org /2/library/curses.html) dann ... – dawg

1

Die gedruckte Länge einer Zeichenfolge hängt vom Typ der Zeichenfolge ab.

Normale Zeichenfolgen in Python 2.x sind in UTF-8. Die Länge von UTF-8 ist gleich den Bytes in String. Ändern Sie den Typ in Unicode, len() liefert jetzt gedruckte Zeichen. So Formatierung funktioniert:

value = 'abcäöücdf' 
len_value = len(value) 
len_uvalue = len(unicode(value,'utf-8')) 
size = self['size'] + len_value-len_uvalue 
print value[:min(len(value),size)].ljust(size)