2013-02-15 1 views
6

Есть ли способ найти (даже лучшее предположение) «напечатанную» длину строки в python? Например. 'potaa \ bto' - 8 символов в len, но всего 6 символов, напечатанных на tty.Печатная длина строки в python

Ожидаемое использование:

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

Nevermind, я неверно истолковали questiom –

+1

Что такое '' plen' из "Азбуки" '? Как насчет '' 123 \ t456 "'? ' "12345 \ R67"'? '" 123456 \ n789 "'? '" 123456 \ r78 \ n9abcd "'? По сути, вам нужно принять решение о правилах для вашего набора символов и написать алгоритм. –

+1

Это действительно сложно. Я пробовал разные подходы, в том числе некоторые подпроцессы.Popen (...). Communication() 'пытается, но безрезультатно. –

ответ

1

По крайней мере, для управляющей последовательности ANSI TTY, это работает:

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) 

Печать:

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

Для забоя \ б или вертикальных вкладок или \ r vs \ n - это зависит от того, как и где печатается, нет?

+0

Я ищу более общее решение ... есть много других непечатаемых символов, чем в моем примере. Да, это зависит от того, как и где, я думаю ... это просто для красивой печати/табуляции, так что это не слишком сильно, если иногда бывает неправильно. – wim

+0

Вы можете пробраться в [проклятия] (http://docs.python.org /2/library/curses.html), то ... – dawg

1

Отпечатанная длина строки зависит от типа строки.

Нормальные строки в python 2.x находятся в utf-8. Длина utf-8 равна , равной байтам в String. Измените тип на unicode, len() поставляет теперь печатные знаки. Так Форматирование работы:

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)