Подтвердить что ты не робот

Проверьте, доступна ли строка python

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

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


Редактировать: я искал/ищу единственную функцию, а не решение по собственной инициативе:

В итоге я получил:

all(ord(c) < 127 and c in string.printable for c in input_str)
4b9b3361

Ответ 1

Как вы сказали, модуль string имеет 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

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

>>> 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)

Ответ 2

try/except выглядит наилучшим образом:

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

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

Ответ 3

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

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

Ответ 4

Эта строка Python 3 содержит все виды специальных символов:

s = 'abcd\x65\x66 äüöë\xf1 \u00a0\u00a1\u00a2 漢字 \a\b\r\t\n\v\\ \231\x9a \u2640\u2642\uffff'

Если вы попытаетесь показать его в консоли (или использовать repr), он довольно хорошо удалит все непечатаемые символы из этой строки:

>>> s
'abcdef äüöëñ \xa0¡¢ 漢字 \x07\x08\r\t\n\x0b\\ \x99\x9a ♀♂\uffff'

Он достаточно умен, чтобы распознавать, например, горизонтальную вкладку (\t) как печатаемую, а вертикальную вкладку (\v) как не печатаемую (отображается как \x0b а не \v).

Любой другой не печатаемый символ также отображается как либо \xNN или \uNNNN в repr. Поэтому мы можем использовать это в качестве теста:

def is_printable(s):
    return not any(repr(ch).startswith("'\\x") or repr(ch).startswith("'\\u") for ch in s)

Могут быть некоторые пограничные символы, например, неразрывный пробел (\xa0) здесь рассматривается как непечатный. Может быть, и не должно быть, но эти специальные могут быть жестко закодированы.


PS

Вы можете сделать это, чтобы извлечь только печатные символы из строки:

>>> ''.join(ch for ch in s if is_printable(ch))
'abcdef äüöëñ ¡¢ 漢字 \r\t\n\\  ♀♂'

Ответ 5

Функция category из модуля unicodedata может удовлетворить ваши потребности. Например, вы можете использовать это, чтобы проверить, есть ли какие-либо управляющие символы в строке, в то же время позволяя использовать символы не ASCII.

>>> import unicodedata

>>> def has_control_chars(s):
...     return any(unicodedata.category(c) == 'Cc' for c in s)

>>> has_control_chars('Hello 世界')
False

>>> has_control_chars('Hello \x1f 世界')
True

Ответ 6

Мое решение - избавиться от любого известного набора символов. это может помочь.

non_printable_chars = set("\n\t\r ")     # Space included intensionally
is_printable = lambda string:bool(set(string) - set(non_printable_chars))
...
...
if is_printable(string):
    print("""do something""")

...

Ответ 7

ctrlchar = "\n\r| "

# ------------------------------------------------------------------------
# This will let you control what you deem 'printable'
# Clean enough to display any binary 

def isprint(chh):
    if ord(chh) > 127:
        return False
    if ord(chh) < 32:
        return False
    if chh in ctrlchar:
        return False
    if chh in string.printable:
        return True
    return False

Ответ 8

# Here is the full routine to display an arbitrary binary string
# Python 2

ctrlchar = "\n\r| "

# ------------------------------------------------------------------------

def isprint(chh):
    if ord(chh) > 127:
        return False
    if ord(chh) < 32:
        return False
    if chh in ctrlchar:
        return False
    if chh in string.printable:
        return True
    return False


# ------------------------------------------------------------------------
# Return a hex dump formatted string

def hexdump(strx, llen = 16):
    lenx = len(strx)
    outx = ""
    for aa in range(lenx/16):
        outx += " "
        for bb in range(16):
            outx += "%02x " % ord(strx[aa * 16 + bb])
        outx += " | "     
        for cc in range(16):
            chh = strx[aa * 16 + cc]
            if isprint(chh):
                outx += "%c" % chh
            else:
                outx += "."
        outx += " | \n"

    # Print remainder on last line
    remn = lenx % 16 ;   divi = lenx / 16
    if remn:
        outx += " "
        for dd in range(remn):
            outx += "%02x " % ord(strx[divi * 16 + dd])
        outx += " " * ((16 - remn) * 3) 
        outx += " | "     
        for cc in range(remn):
            chh = strx[divi * 16 + cc]
            if isprint(chh):
                outx += "%c" % chh
            else:
                outx += "."
        outx += " " * ((16 - remn)) 
        outx += " | \n"


    return(outx)