Python непечатаемые символы в строке

Показать непечатаемые символы в строке

Можно ли визуализировать непечатные символы в строке Python с шестнадцатеричными значениями?

Например, если у меня есть строка с новой строкой внутри, я хотел бы заменить ее на \x0a ,

Я знаю, что есть repr() что даст мне. \n , но я ищу шестнадцатеричную версию.

5 ответов

Вам придется сделать перевод вручную; например, просмотрите строку с регулярным выражением и замените каждое вхождение на шестнадцатеричный эквивалент.

import re replchars = re.compile(r'[\n\r]') def replchars_to_hex(match): return r'\x'.format(ord(match.group())) replchars.sub(replchars_to_hex, inputtext) 

Приведенный выше пример соответствует только символам новой строки и возврату каретки, но вы можете расширить, какие символы сопоставляются, в том числе используя \x escape-коды и диапазоны.

>>> inputtext = 'Some example containing a newline.\nRight there.\n' >>> replchars.sub(replchars_to_hex, inputtext) 'Some example containing a newline.\\x0aRight there.\\x0a' >>> print(replchars.sub(replchars_to_hex, inputtext)) Some example containing a newline.\x0aRight there.\x0a 

Я не знаю ни одного встроенного метода, но это довольно легко сделать, используя понимание:

import string printable = string.ascii_letters + string.digits + string.punctuation + ' ' def hex_escape(s): return ''.join(c if c in printable else r'\x'.format(ord(c)) for c in s) 

Я немного опоздал на вечеринку, но если вам это нужно для простой отладки, я обнаружил, что это работает:

string = "\n\t\nHELLO\n\t\n\a\17" procd = [c for c in string] print(procd) # Prints ['\n,', '\t,', '\n,', 'H,', 'E,', 'L,', 'L,', 'O,', '\n,', '\t,', '\n,', '\x07,', '\x0f,'] 

Ужасно, но это помогло мне найти непечатаемые символы в строке.

Модификация решения ecatmur для обработки непечатаемых символов, отличных от ASCII, делает его менее тривиальным и более неприятным:

def escape(c): if c.printable(): return c c = ord(c) if c '.format(c) elif c '.format(c) else: return r'\U'.format(c) def hex_escape(s): return ''.join(escape(c) for c in s) 

Конечно, если str.isprintable не совсем то определение, которое вы хотите, вы можете написать другую функцию. (Обратите внимание, что это очень отличается от того, что в string.printable — помимо обработки не ASCII-печатных и непечатных символов, он также учитывает \n , \r , \t , \x0b , а также \x0c как не для печати.

Читайте также:  Что такое строки сишарп

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

def escape(c): if c.printable(): return c elif c '.format(ord(c)) else: return c.encode('unicode_escape').decode('ascii') 

На самом деле, независимо от того, что вы делаете, вам придется справиться \r , \n , а также \t явно, потому что все известные мне встроенные функции и функции stdlib будут избегать их через эти специальные последовательности вместо их шестнадцатеричных версий.

Существует также способ печатать непечатаемые символы в том смысле, что они выполняются как команды в строке, даже если они не видны (прозрачны) в строке, и их присутствие можно наблюдать, измеряя длину строки с помощью len а также просто поместив курсор мыши в начало строки и просмотрев / подсчитав, сколько раз вам нужно нажать клавишу со стрелкой, чтобы перейти от начала до конца, так как, как ни странно, некоторые отдельные символы могут иметь длину, например, 3, что кажется озадачивающим. (Не уверен, что это уже было продемонстрировано в предыдущих ответах)

В этом примере снимка экрана ниже я вставил 135-битную строку, которая имеет определенную структуру и формат (который мне пришлось вручную создать заранее для определенных битовых позиций и ее общей длины), так что она интерпретируется как ascii конкретной программой I’m, и в полученной напечатанной строке есть непечатаемые символы, такие как ‘разрыв строки’, который буквально вызывает разрыв строки (исправление: подача формы, новая страница, я имел в виду, а не разрыв строки) в печатном выходе есть дополнительный целая пустая строка между напечатанным результатом (см. ниже):

Input a string:100100001010000000111000101000101000111011001110001000100001100010111010010101101011100001011000111011001000101001000010011101001000000 HPQGg]+\,vE!:@ >>> len('HPQGg]+\,vE!:@') 17 >>> 

В приведенном выше фрагменте кода попробуйте скопировать и вставить строку HPQGg]+\,vE!:@ прямо с этого сайта и посмотрите, что произойдет, когда вы вставите его в Python IDLE.

Читайте также:  Normalize vectors in python

Подсказка: вам нужно нажать на стрелку / курсор три раза, чтобы пересечь две буквы из P к Q даже если они появляются рядом друг с другом, так как на самом деле File Separator команда ascii между ними.

Однако, несмотря на то, что мы получаем одно и то же начальное значение при декодировании его как байтового массива в шестнадцатеричный, если мы преобразуем этот шестнадцатеричный код обратно в байты, они выглядят по-другому (возможно, отсутствие кодировки, не уверен), но в любом случае приведенный выше вывод программы печатает непечатаемые символы (я наткнулся на это случайно, пытаясь разработать метод / эксперимент сжатия).

>>> bytes(b'HPQGg]+\,vE!:@').hex() '48501c514767110c5d2b5c2c7645213a40' >>> bytes.fromhex('48501c514767110c5d2b5c2c7645213a40') b'HP\x1cQGg\x11\x0c]+\\,vE!:@' >>> (0x48501c514767110c5d2b5c2c7645213a40 == 0b100100001010000000111000101000101000111011001110001000100001100010111010010101101011100001011000111011001000101001000010011101001000000) True >>> 

В приведенной выше 135-битной строке первые 16 групп по 8 бит со стороны прямого байта кодируют каждый символ (включая непечатаемый), тогда как последняя группа из 7 бит приводит к @ символ, как показано ниже:

А здесь в виде текста — расшифровка 135-битной строки:

10010000 = H (72) 10100000 = P (80) 00111000 = x1c (28 for File Separator) * 10100010 = Q (81) 10001110 = G(71) 11001110 = g (103) 00100010 = x11 (17 for Device Control 1) * 00011000 = x0c (12 for NP form feed, new page) * 10111010 = ] (93 for right bracket ‘]’ 01010110 = + (43 for + sign) 10111000 = \ (92 for backslash) 01011000 = , (44 for comma, ‘,’) 11101100 = v (118) 10001010 = E (69) 01000010 = ! (33 for exclamation) 01110100 = : (58 for colon ‘:’) 1000000 = @ (64 for ‘@’ sign) 

Итак, в заключение, ответ на подвопрос об отображении непечатаемого в шестнадцатеричном виде, в массиве байтов, расположенном выше, появляются буквы x1c которые обозначают команду разделителя файлов, которая также была отмечена в подсказке. Массив байтов можно рассматривать как строку, если исключить префикс b слева, и снова это значение отображается в строке печати, хотя и невидимо (хотя его присутствие можно наблюдать, как показано выше, с помощью подсказки и len команда).

Читайте также:  Как сделать счетчик питон

Источник

Функция String isprintable() в Python

Функция String isprintable() в Python возвращает True, если все символы в строке печатаются или строка пуста, в противном случае – False.

Непечатаемые символы – это те символы, которые определены в базе данных символов Unicode, как «Другое» или «Разделитель», за исключением пробела ASCII (0x20), который считается печатаемым.

Обратите внимание, что печатаемые символы в этом контексте – это те, которые не следует экранировать при вызове repr() для строки.

Давайте посмотрим на несколько примеров функции String isprintable().

s = 'Hi Hello World' print(s.isprintable())

Вывод: True, потому что все символы печатаются, а пробел считается печатным символом.

Вывод: True, потому что пустая строка считается печатаемой.

s = 'Hi\tHello' print(s.isprintable())

Вывод: False, потому что \t не печатаемый символ.

s = 'Hi\nHello' print(s.isprintable())

Вывод: False, потому что \n не печатаемый символ.

s = 'Hi\'Hello' print(s.isprintable()) print(s)

Давайте посмотрим на другой пример с некоторыми escape-символами.

s = 'Hi\bHello' print(s.isprintable()) print(s)

Символ \b считается непечатаемым.

s = 'Hi\aHello' print(s.isprintable()) print(s)

Символ \a считается непечатаемым.

s = 'Hi\u0066Hello' print(s.isprintable()) print(s) s = 'Hi\u0009Hello' print(s.isprintable()) print(s)
True HifHello False Hi Hello

\U0066 (f) можно распечатать, тогда как \u0009 (\t) нельзя распечатать.

Распечатать список всех непечатаемых символов

Вот простой фрагмент кода для печати списка деталей непечатаемых символов.

count = 0 for codepoint in range(2 ** 16): ch = chr(codepoint) if not ch.isprintable(): print(u''.format(codepoint)) count = count + 1 print(f'Total Number of Non-Printable Unicode Characters = ')
0000 0001 0002 . fffb fffe ffff Total Number of Non-Printable Unicode Characters = 10249

Источник

Оцените статью