Показывать непечатаемые символы в строке
можно ли визуализировать непечатаемые символы в строке python с его шестнадцатеричными значениями?
например, если у меня есть строка с новой строкой внутри, я хотел бы заменить ее на x0a
.
Я знаю, что есть repr()
что даст мне ...n
, но я ищу версию hex.
5 ответов
вам придется сделать перевод вручную; пройдите через строку с регулярным выражением, например, и замените каждое вхождение шестнадцатеричным эквивалентом.
import re
replchars = re.compile(r'[\n\r]')
def replchars_to_hex(match):
return r'\x{0:02x}'.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{0:02x}'.format(ord(c)) for c in s)
Я немного опоздала на вечеринку, но если вам это нужно для простой отладки, я обнаружил, что это работает:
string = "\n\t\nHELLO\n\t\n\a"
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 <= 0xff:
return r'\x{0:02x}'.format(c)
elif c <= '\uffff':
return r'\u{0:04x}'.format(c)
else:
return r'\U{0:08x}'.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 <= '\xff':
return r'\x{0:02x}'.format(ord(c))
else:
return c.encode('unicode_escape').decode('ascii')
действительно, независимо от того, что вы делаете, вам придется справиться \r
, \n
и \t
явно, потому что все встроенные и stdlib функции, о которых я знаю, будут избегать их через эти специальные последовательности вместо их шестнадцатеричных версий.
Я сделал что-то похожее на наследование str
подкласс с пользовательским __repr__()
метод, который сделал то, что хотел. Это не совсем то, что вы ищете, но может дать вам некоторые идеи.
# -*- coding: iso-8859-1 -*-
# special string subclass to override the default
# representation method. main purpose is to
# prefer using double quotes and avoid hex
# representation on chars with an ord > 128
class MsgStr(str):
def __repr__(self):
# use double quotes unless there are more of them within the string than
# single quotes
if self.count("'") >= self.count('"'):
quotechar = '"'
else:
quotechar = "'"
rep = [quotechar]
for ch in self:
# control char?
if ord(ch) < ord(' '):
# remove the single quotes around the escaped representation
rep += repr(str(ch)).strip("'")
# embedded quote matching quotechar being used?
elif ch == quotechar:
rep += "\"
rep += ch
# else just use others as they are
else:
rep += ch
rep += quotechar
return "".join(rep)
if __name__ == "__main__":
s1 = '\tWürttemberg'
s2 = MsgStr(s1)
print "str s1:", s1
print "MsgStr s2:", s2
print "--only the next two should differ--"
print "repr(s1):", repr(s1), "# uses built-in string 'repr'"
print "repr(s2):", repr(s2), "# uses custom MsgStr 'repr'"
print "str(s1):", str(s1)
print "str(s2):", str(s2)
print "repr(str(s1)):", repr(str(s1))
print "repr(str(s2)):", repr(str(s2))
print "MsgStr(repr(MsgStr('\tWürttemberg'))):", MsgStr(repr(MsgStr('\tWürttemberg')))