Python 2.7 Декодирование UTF-8 и unicode-escape в python вызывает UnicodeEncodeError - PullRequest
0 голосов
/ 06 сентября 2018

У меня есть файл tsv, который в некоторых строках содержит столбец смешанного формата, например: Hapoel_Be\u0027er_Sheva_A\u002eF\u002eC\u002e, который должен быть Hapoel_Be'er_Sheva_A.F.C..

А вот код, который я использую для чтения файла и разделения столбцов:

with open(path, 'rb') as f:
  for line in f:
      cols = line.decode('utf-8').split('\t')
      text = cols[3].decode('unicode-escape') #Here is the column that has the above mentioned mixed format

Сообщение об ошибке:

UnicodeEncodeError: 'ascii' codec can't encode character u'\u0160' in position 6: ordinal not in range(128)

Хотелось бы узнать, как конвертировать из первого смешанного формата в другой при чтении файла? Я использую Python 2.7.

Большое спасибо,

Ответы [ 2 ]

0 голосов
/ 06 сентября 2018

Вы можете использовать decode('unicode-escape') для преобразования этих шестнадцатеричных последовательностей в символы.

>>> 'Hapoel_Be\\u0027er_Sheva_A\\u002eF\\u002eC\\u002e'.decode('unicode-escape')
u"Hapoel_Be'er_Sheva_A.F.C."

Редактировать: согласно вашему обновлению вопроса, у вас на самом деле есть комбинация шестнадцатеричных последовательностей и символов Юникода вне диапазона ASCII. Ошибка происходит из-за автоматического преобразования, которое пытается выполнить Python 2.7, когда вы пытаетесь использовать .decode() в строке Unicode - decode работает только со строками байтов, поэтому он пытается преобразовать из Unicode, используя кодек ASCII. Python 3 не допустит этой ошибки.

Чтобы исправить это, вам нужно двойное преобразование: одно для преобразования не-ASCII символов в шестнадцатеричные последовательности, а другое для их обратного преобразования. Кодек 'unicode-escape' удвоит обратную косую черту, поэтому их также необходимо исправить.

>>> print u'Hapoel_Be\\u0027er_Sheva_A\\u002eF\\u002eC\\u002e\u0160'.encode('unicode-escape').replace(b'\\\\u', b'\\u').decode('unicode-escape')
Hapoel_Be'er_Sheva_A.F.C.Š
0 голосов
/ 06 сентября 2018

Вы можете использовать ast.literal_eval для преобразования необработанных байтов в Unicode

import ast

raw_bytes = br'Hapoel_Be\u0027er_Sheva_A\u002eF\u002eC\u002e'
print(raw_bytes)  # b'Hapoel_Be\u0027er_Sheva_A\u002eF\u002eC\u002e'

unicode_string = ast.literal_eval('"{}"'.format(raw_bytes.decode('utf8')))

вывод unicode_string:

Hapoel_Be'er_Sheva_A.F.C.

Обновление - протестировано в Python 2.7 и работает шарм

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...