Python не удается закодировать плохой Unicode в ascii

#python #unicode

#python #unicode

Вопрос:

У меня есть некоторый код Python, который получает строку с неверным юникодом в нем. Когда я пытаюсь игнорировать неверные символы, Python по-прежнему захлебывается (версия 2.6.1). Вот как это воспроизвести:

 s = 'adxc2-venxc2-ture'
s.encode('utf8', 'ignore')
  

Он выдает

 UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 2: ordinal not in range(128)
  

Что я делаю не так?

Комментарии:

1. Вы уверены, что не хотите вместо этого использовать s.decode(‘utf8’, ‘ignore’)?

2. Да, вы правы. Упс 🙂

Ответ №1:

Преобразование строки в экземпляр Unicode выполняется str.decode() в Python 2.x:

  >>> s.decode("ascii", "ignore")
 u'ad-ven-ture'
  

Комментарии:

1. Обратите внимание, что с кодировкой OP (utf-8) вместо ASCII вы получите u'adventure' . На самом деле я предпочитаю unicode(utf8_string, 'utf-8', 'ignore') , поскольку так понятнее, что вы создаете строку unicode.

2. Также есть s.decode('ascii', 'replace') который можно использовать, чтобы получить представление о проблемах.

Ответ №2:

Вы путаете «unicode» и «utf-8». Ваша строка s не является юникодом; это байтовая строка в определенной кодировке (но не UTF-8, скорее iso-8859-1 или что-то в этом роде.) Переход от байтовой строки к unicode осуществляется путем декодирования данных, а не кодирования. Переход от unicode к bytestring — это кодирование. Возможно, вы имели в виду создать s строку в юникоде:

 >>> s = u'adxc2-venxc2-ture'
>>> s.encode('utf8', 'ignore')
'adxc3x82-venxc3x82-ture'
  

Или, возможно, вы хотите обработать байтовую строку как UTF-8, но игнорировать недопустимые последовательности, и в этом случае вы должны декодировать байтовую строку с помощью ‘ignore’ в качестве обработчика ошибок:

 >>> s = 'adxc2-venxc2-ture'
>>> u = s.decode('utf-8', 'ignore')
>>> u
u'adventure'
>>> u.encode('utf-8')
'adventure'