Python UnicodeDecodeError в умных кавычках - PullRequest
0 голосов
/ 02 ноября 2018

У меня есть скрипт на python, и недавно я заметил, что я получаю некоторые ошибки кодирования при вводе. Я заметил, что «умные цитаты» вызывают проблемы. Я хотел бы знать совет о том, как преодолеть это. Я использую Python 2, поэтому необходимо указать моему сценарию, что я хочу кодировать все в UTF-8.


Я думал, что этого было достаточно:

mystring.encode("utf-8")

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

mystring = "hi"
mystring.encode("utf-8")

вывод

'hi'

Но для этого:

mystring2 = "’"
mystring.encode("utf-8")

вывод

UnicodeDecodeError
  Traceback (most recent call last)
    <ipython-input-21-f563327dcd27> in <module>()
    ----> 1 mystring.encode("utf-8")
  UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in
  position 0: ordinal not in range(128)

Я создал функцию для обработки ввода JSON, который я получаю (иногда я получаю нулевые / None значения, а иногда числовые значения, хотя в основном это Unicode, поэтому у меня есть пара операторов if):

def xstr(s):
    if s is None:
        return ''
    if isinstance(s, basestring):
        return str(s.encode("utf-8"))
    else:
        return str(s)

Это работало довольно хорошо (до этой проблемы умных цитат)

У меня есть два вопроса:

  1. Почему «умные кавычки» не могут быть закодированы в UTF-8, и есть ли другие ограничения UTF-8 или я полностью неверно истолковываю то, что вижу?

  2. Является ли подход, который я использовал (т. Е. С помощью моей пользовательской функции), лучшим способом справиться с этим? Я попытался использовать попытку / кроме, чтобы поймать случаи умных цитат, но это не сработало.

1 Ответ

0 голосов
/ 02 ноября 2018

Python не может закодировать строку, потому что он не знает ее текущую кодировку. Вам нужно будет использовать u"’" в Python 2, чтобы сообщить Python, что это строка Unicode. ("\xe2" оказывается первым байтом кодировки UTF-8 этого символа, но Python не знает, что он находится в UTF-8, потому что вы этого не сказали. Вы могли бы поместить комментарий -*- coding: utf-8 -*- рядом с верх вашего файла, или однозначно представляйте символ как u"\u2219".)

Точно так же, чтобы преобразовать строку, которую вы читаете с диска, вам нужно преобразовать ее в Unicode, чтобы затем можно было кодировать как UTF-8.

print(s.decode('iso-8859-1').encode('utf-8'))

Здесь, конечно, 'iso-8859-1' - это просто случайное предположение. Вы должны знать кодировку или рискнуть получить неправильный вывод.

...