2010-09-03 3 views
19

У меня есть код, который извлекает данные из com-порта, и я хочу убедиться, что то, что я получил, является печатаемой строкой (то есть ASCII, может быть, UTF-8) перед ее печатью. Есть ли функция для этого? В первой половине дозонных мест, которые я смотрел, не было ничего похожего на то, что я хочу. (string has printable, но я ничего не видел (там или в the string methods), чтобы проверить, если каждый символ в одной строке в другойПроверьте, не печатается ли строка python

. Примечание: Управляющие символы не печати для моих целей


.

Edit: Я/ищу одну функцию, а не рулон собственное решение:

То, что я закончил с это:

all(ord(c) < 127 and c in string.printable for c in input_str) 
+0

Если нет готового решения, вы можете DIY с 'string.printable':' Printables = множество (string.printable); если все (char в printables для char в вашей_странице): ... ' – delnan

ответ

3

try/except кажется, лучший способ:

def isprintable(s, codec='utf8'): 
    try: s.decode(codec) 
    except UnicodeDecodeError: return False 
    else: return True 

я бы не полагаться на string.printable, которые могли бы счесть «непечатные» символы управления, которые могут часто быть «напечатаны» для целей управления терминала (например, в " colorization "ANSI escape-последовательностей, если ваш терминал соответствует ANSI). Но это, конечно, зависит от ваших точных целей для желающих проверить это -)

+2

string.printable хорошо определен. «комбинация цифр, букв, знаков препинания и пробелов». Whitesapce OTOH немного меньше: «В большинстве систем это включает в себя пространство символов, вкладку, линию, возврат, форму и вертикальную вкладку». – BCS

+2

@BCS, это в основном та же концепция, что и «старый» макрос «isprint» C, и демонстрирует точно такие же недостатки (без управляющих последовательностей/escape-последовательностей), но многие терминалы и принтеры могут принимать некоторые управляющие/escape-последовательности для косметических целей, таких как расцветка, и, в зависимости от целей приложения, запрещение таких символов на выходе может поэтому оказаться неразумным). –

+0

Моя забота заключается в том, что пробел может включать * больше *, чем эти 6 символов. Я знаю, что если мой источник данных когда-либо содержит «контрольные символы», я могу предположить, что они являются нежелательными. – BCS

36

Как вы уже сказали string module has printable, так что это просто случай проверки, если все символы в строке в printable:

>>> hello = 'Hello World!' 
>>> bell = chr(7) 
>>> import string 
>>> all(c in string.printable for c in hello) 
True 
>>> all(c in string.printable for c in bell) 
False 

Вы можете преобразовать обе строки в наборах - так что набор будет содержать каждый символ в строке один раз - и проверить, если набор, созданный вашей строки is a subset of печатаемые символы:

>>> printset = set(string.printable) 
>>> helloset = set(hello) 
>>> bellset = set(bell) 
>>> helloset 
set(['!', ' ', 'e', 'd', 'H', 'l', 'o', 'r', 'W']) 
>>> helloset.issubset(printset) 
True 
>>> set(bell).issubset(printset) 
False 

таким образом, в резюме , Вы, вероятно, хотите сделать это:

import string 
printset = set(string.printable) 
isprintable = set(yourstring).issubset(printset) 
+4

Я как бы надеялся на то, что вы откажетесь от своего собственного решения. Почему heck не использует python как функцию? – BCS

+6

«Почему у heck нет python это как функция?»: Это решение и другие подобные ему тривиальные композиции встроенных возможностей python. если ему было присвоено специальное имя, и всякая полезная, но тривиальная функция была также благословлена ​​именем, тогда пространство имен python было бы ужасно загромождено. эта краткая композиция выглядит так же легко, как некоторые гипотетические 'stringutil.stringisprintable (myvar)', за исключением того, что нет необходимости поддерживать этот дополнительный модуль. – SingleNegationElimination

+3

Выполняет ли это что-либо, кроме ASCII? – jpmc26

3
>>> # Printable 
>>> s = 'test' 
>>> len(s)+2 == len(repr(s)) 
True 

>>> # Unprintable 
>>> s = 'test\x00' 
>>> len(s)+2 == len(repr(s)) 
False 
+6

Это просто слишком умно. Вы, наверное, не должны этого делать, но +1 все равно, потому что это заставило меня улыбнуться. – SingleNegationElimination

+4

работает только для ascii. – BCS

+4

Он не подходит для 's = 'a \ nb''. –

Смежные вопросы