Проблема Python с неправильно сформированными строками, содержащими x
В какой-то момент наш скрипт python получает такую строку:
In [1]: ab = 'asdxeffective'
In [2]: print ab
asd�fectve \ \k\
Данные повреждены нам нужно escape x правильно интерпретировать как x, но c не имеет особого значения в строке, поэтому должен быть неповрежденным.
Пока что самое близкое решение, которое я нашел, это сделать что-то вроде:
In [1]: ab = 'asdxeffectve \ \\ \\\k\\\'
In [2]: print ab.encode('string-escape').replace('\\', '\').replace("\'", "'")
asdxeffectve \ \k\
Вывод, взятый из IPython, я предположил, что ab-это строка, а не строка unicode (в более позднем случае нам придется сделать что-то вроде этого:
def escape_string(s):
if isinstance(s, str):
s = s.encode('string-escape').replace('\\', '\').replace("\'", "'")
elif isinstance(s, unicode):
s = s.encode('unicode-escape').replace('\\', '\').replace("\'", "'")
return s
4 ответа:
'\\'это то же самое, что'\x5c'. Это просто два разных способа записать символ обратной косой черты какстроковый литерал Python .Эти литеральные строки:
r'\c','\\c','\x5cc','\x5c\x63'являются идентичнымиstrобъекты в памяти.
'\xef'является одним байтом (239как целое число), ноr'\xef'(так же, как'\\xef') является 4-байтовой строкой:'\x5c\x78\x65\x66'.Если
s[0]возвращает'\xef', то это то, чтоsобъект на самом деле содержит. Если это неправильно, то исправьте источник данные.
Примечание:
string-escapeтакже убегает\nи тому подобное:>>> print u'''\xef\c\\\N{SNOWMAN}"'\ ... ☃\u2603\"\'\n\xa0'''.encode('unicode-escape') \xef\\c\\\u2603"'\u2603\u2603"'\n\xa0 >>> print b'''\xef\c\\\N{SNOWMAN}"'\ ... ☃\u2603\"\'\n\xa0'''.encode('string-escape') \xef\\c\\\\N{SNOWMAN}"\'\xe2\x98\x83\\u2603"\'\n\xa0
backslashreplaceиспользуется только для символов, вызывающихUnicodeEncodeError:>>> print u'''\xef\c\\\N{SNOWMAN}"'\ ... ☃\u2603\"\'\n\xa0''' ï\c\☃"'☃☃"' >>> print b'''\xef\c\\\N{SNOWMAN}"'\ ... ☃\u2603\"\'\n\xa0''' �\c\\N{SNOWMAN}"'☃\u2603"' � >>> print u'''\xef\c\\\N{SNOWMAN}"'\ ... ☃\u2603\"\'\n\xa0'''.encode('ascii', 'backslashreplace') \xef\c\\u2603"'\u2603\u2603"' \xa0 >>> print b'''\xef\c\\\N{SNOWMAN}"'\ ... ☃\u2603\"\'\n\xa0'''.decode('latin1').encode('ascii', 'backslashreplace') \xef\c\\N{SNOWMAN}"'\xe2\x98\x83\u2603"' \xa0
Обратные косые черты вводят "escape-последовательности".
\xспециально позволяет указать байт, который задается в виде двух шестнадцатеричных цифр после x.ef- это две шестнадцатеричные цифры, следовательно, вы не получите ошибки. Удвоьте обратную косую черту, чтобы избежать ее, или используйте необработанную строкуr"\xeffective".Edit: хотя консоль Python может показать вам
'\\', это является именно тем, что вы ожидаете. Вы просто говорите, что ожидаете чего-то другого, потому что путаете строку и ее представление. Это струна. содержит одну обратную косую черту. Если бы вы вывели его с помощьюНо строковый литерал
'\'плохо сформирован (не закрыт, потому что\'является Апострофом, а не обратной косой чертой и концом строкового литерала), поэтомуrepr, который форматирует результаты в интерактивной оболочке, не производит его. Вместо этого он создает строковый литерал, который можно вставить в исходный код Python и получить тот же строковый объект. Например,len('\\') == 1.
Escape-последовательность
\xобозначает символ Юникода в строке, аefинтерпретируется как шестнадцатеричный код. Вы можете очистить строку, добавив дополнительный\, или же сделать ее сырой строкой (r'\xeffective').>>> r'\xeffective'[0] '\\'EDIT: вы можете преобразовать существующую строку, используя следующий хак:
>>> a = '\xeffective' >>> b = repr(a).strip("'") >>> b '\\xeffective'