Python + PostgreSQL + странный ASCII = ошибка кодирования UTF8

У меня есть строки ASCII, которые содержат символ "\x80" представить европейский символ:

>>> print "\x80"
€

При вставке строковых данных, содержащих этот символ в мою базу данных, я добираюсь:

psycopg2.DataError: invalid byte sequence for encoding "UTF8": 0x80
HINT:  This error can also happen if the byte sequence does not match the encodi
ng expected by the server, which is controlled by "client_encoding".

Я - unicode новичок. Как я могу преобразовать свои строки, содержащие "\x80" к допустимому UTF-8, содержащему тот же самый европейский символ? Я попытался звонить .encode и .decode на различных строках, но сталкивается с ошибками:

>>> "\x80".encode("utf-8")
Traceback (most recent call last):
  File "<pyshell#14>", line 1, in <module>
    "\x80".encode("utf-8")
UnicodeDecodeError: 'ascii' codec can't decode byte 0x80 in position 0: ordinal not in range(128)
6
задан Claudiu 7 June 2010 в 17:22
поделиться

1 ответ

вопрос начинается с ложной посылки:

У меня есть строки ascii, которые содержат символ «\ x80» для обозначения символа евро.

Символы ASCII находятся в диапазоне от «\ x00» до «\ x7F» включительно.

Ранее принятый, теперь удаленный ответ действовал при двух грубых заблуждениях (1) о том, что locale == encoding (2), что кодировка latin1 отображает "\ x80" в символ евро.

Фактически, все кодировки ISO-8859-x отображают "\ x80" в U + 0080, который является одним из управляющих символов C1, а не символом евро. Только 3 из этих кодировок (x в (7, 15, 16)) предоставляют символ евро, как "\ xA4". См. эту статью в Википедии .

Вам необходимо знать , в какой кодировке находятся ваши данные.На какой машине он был создан? Как? Локаль, в которой он был создан (не обязательно ваш), может дать вам подсказку.

Обратите внимание, что «Мои данные закодированы в latin1» рядом с «Чек по почте» и «Конечно, я буду любить тебя утром». Ваши данные, вероятно, закодированы в одной из кодировок cp125x, имеющихся на платформах Windows. Обратите внимание, что все они, кроме cp1251 (Windows Cyrillic), отображают "\ x80" на символ евро:

>>> ['\x80'.decode('cp125' + str(x), 'replace') for x in range(9)]
[u'\u20ac', u'\u0402', u'\u20ac', u'\u20ac', u'\u20ac', u'\u20ac', u'\u20ac', u'\u20ac', u'\u20ac']

Обновление в ответ на комментарий OP

Я читаю эти данные из файла, например open (fname) .read () . Он содержит строки с \ x80, которые представляют символ евро. это просто текстовый файл. он генерируется другой программой, но я не знаю, как он генерирует текст. какое было бы хорошее решение? Я думаю, что могу предположить, что он выводит "\ x80" для символа евро, то есть я могу предположить, что он закодирован с помощью cp125x, который имеет этот символ как евро.

Это немного сбивает с толку: сначала вы говорите

Он содержит строки с \ x80 в них, которые представляют символ евро

Но позже вы скажете

Я думаю, я могу предположить, что он выводит "\ x80 "для символа евро

Поясните, пожалуйста.

Выбор подходящей кодировки cp125x: Где (географическое положение) был создан файл? На каком языке (ах) написан текст? Любые символы кроме предполагаемого евро со значениями> "\ x7f"? Если да, то какие из них и в каком контексте они используются?

Обновление 2 Если вы не «знаете, как написана программа», ни вы, ни мы не можем составить мнение о том, всегда ли она использует «\ x80 "для символа евро.Хотя поступить иначе было бы монументальной глупостью, этого нельзя исключать.

Если текст написан на английском языке и / или он написан в США, и / или он написан на платформе Windows, то можно с достаточной уверенностью сказать, что cp1252 - это правильный путь. .. пока вы не получите доказательств обратного, и в этом случае вам нужно будет самостоятельно угадать кодировку или ответить на вопросы (какой язык, какая местность).

12
ответ дан 9 December 2019 в 20:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: