Проблема в кодировании / декодировании в Python 3 с не ascii символом - PullRequest
0 голосов
/ 28 декабря 2018

Я пытаюсь использовать python3 unicode_escape для экранирования \ n в моей строке, но проблема в том, что во всей строке присутствуют не-ascii символы, и если я использую utf8 для кодирования, а затем декодирую байты с использованием unicode_escape, тогдаспециальный персонаж искажается.Можно ли как-нибудь экранировать \ n новой строкой, не используя специальный символ?

s = "hello\\nworld└--"
print(s.encode('utf8').decode('unicode_escape'))

Expected Result:
hello
world└--

Actual Result:
hello
worldâ--

Ответы [ 3 ]

0 голосов
/ 28 декабря 2018

Я полагаю, что проблема, с которой вы столкнулись, заключается в том, что unicode_escape устарела в Python 3.3, и, похоже, предполагается, что ваш код является 'latin-1' из-за того, что он является исходным кодеком, используемым в функции unicode_excape..

Глядя на документацию по python для кодеков , мы видим, что Encoding suitable as the contents of a Unicode literal in ASCII-encoded Python source code, except that quotes are not escaped. Decodes from Latin-1 source code. Beware that Python source code actually uses UTF-8 by default., который говорит нам, что unicode_escape предполагает, что ваш текст соответствует ISO Latin-1.Таким образом, если мы запустим ваш код с кодировкой latin1, мы получим эту ошибку:

s.encode('latin1')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'latin-1' codec can't encode character '\u2514' in position 12: ordinal not in range(256)

И ошибка Unicode-символа равна '\u2514', которая при преобразовании равна '└', самый простой способ выразить это: символ не может бытьиспользуется в строке Latin-1, поэтому вы получаете другой символ.

Я также считаю правильным указать, что в вашей строке есть '\\n', а не просто '\n', дополнительный обратный слеш означает этот символне возврат каретки, но вместо этого он игнорируется, обратный слеш указывает на игнорирование '\n'.Возможно, попробуйте не использовать \\n ...

0 голосов
/ 29 декабря 2018

Как заметил пользователь wowcha, кодек unicode-escape предполагает кодировку latin-1, но ваша строка содержит символ, который не кодируется как latin-1.

>>> s = "hello\\nworld└--"
>>> s.encode('latin-1')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'latin-1' codec can't encode character '\u2514' in position 12: ordinal not in range(256)

Кодирование строки как utf-8 обходит проблему кодирования, но приводит к mojibake при декодировании из unicode-escape

Решение заключается в использовании обработчика ошибок backslashreplace при кодировании.Это преобразует символ проблемы в escape-последовательность, которая может быть закодирована как latin-1 и не будет искажена при декодировании из unicode-escape.

>>> s.encode('latin-1', errors='backslashreplace')
b'hello\\nworld\\u2514--'

>>> s.encode('latin-1', errors='backslashreplace').decode('unicode-escape')
'hello\nworld└--'

>>> print(s.encode('latin-1', errors='backslashreplace').decode('unicode-escape'))
hello
world└--
0 голосов
/ 28 декабря 2018

Попробуйте удалить второй escape-слеш и декодировать, используя utf8:

>>> s = "hello\nworld└--"
>>> print(s.encode('utf8').decode('utf8'))
hello
world└--
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...