Строковое кодирование и декодирование возможно из latin1 и utf8

Недавно я наткнулся на базу данных MySQL, которая была закодирована с использованием Latin1 и выполняла рендеринг при просмотре в символах вопросительного знака браузера. Чтобы исправить это, мы изменили кодировку DB на utf8 и Collation на utf8_general_ci во всех наших таблицах, но уже сохраненные данные все еще показывались с символами вопросительного знака, все хранение и опрос данных из mysql в браузер это было сделано php, я удостоверился, что utf8 использовался и на php, и даже запускал сетевые имена utf8, как многие предлагали в Интернете, проблема в том, что теперь у меня появились странные символы, такие как Ã Â, в строках, которые, как мы знали, не имели их,

Примеры данных

Хранится:

EMMANUEL PE \ xc3 \xc2\u2018A ГОМЕС ПОРТУГАЛИЯ

Вынесено:

ЭММАНУЭЛЬ ПЕВАЯ ГОМЕС ПОРТУГАЛИЯ

Надлежащая:

ЭММАНУЭЛЬ ПЕНЬЯ ГОМЕС ПОРТУГАЛИЯ


Хранится:

Луис Херн \xe1ndez-Higareda

Вынесено:

Луис Эрнандес-Хигареда

Надлежащая:

Луис Эрнандес-Хигареда


Хранится:

Тереза ​​де Хес \xc3\u0192\xc2\xbas Галисия G\xc3\u0192\xc2\xb3mez

Вынесено:

Тереза ​​де Хесус Галисия Гемес

Надлежащая:

Тереза ​​Хесус Галисия Гомес


Хранится:

DR. JOS \ xc3 \ u0192 \ xc2 \ u2030 ABEN \ xc3 \ u0192 \ xc2 \ x81MAR RIC \ xc3 \ u0192 \ xc2 \ x81RDEZ GARC \ xc3 \ u0192 \ xc2 \ x8dA

Надлежащая:

DR. Хосе Абенмар Ричардез Гарса

В настоящее время я использую Python для получения данных из БД, я пытаюсь нормализовать Unicode UTF8, но я действительно потерян, вот, насколько я здесь, мне нужно преобразовать то, что в настоящее время выглядит как странно символы для читаемого текста, как показано выше.

что мне здесь не хватает? данные о неисправимом?

Функции https://gist.github.com/2649463

Примечание: из всех примеров есть 1, который правильно отображает (оставлено там, поэтому следует принять во внимание, если дан какой-либо совет, как это исправить)

2 ответа

Решение

Если вы попытались вставить символы, которые не могут быть представлены в latin1 в столбцы, хранящиеся под этой кодировкой символов, эти символы были бы необратимо заменены на ? - информация была потеряна: ваш единственный вариант - переустановить / обновить данные теперь, когда столбец хранится в utf8,

Однако некоторые данные в вашем вопросе не имеют большого смысла. Например:

Хранится:

EMMANUEL PE \ xc3 \ xc2\u2018A ГОМЕС ПОРТУГАЛИЯ

Вы пытаетесь показать байты или символы, которые в настоящее время хранятся? В любом случае, один из \u или же \x escape-коды не имеют смысла.

Вы говорите, что исходные данные были закодированы как latin1; в этом наборе символов символ С кодируется как 0xd1, Вы говорите, что затем преобразовали данные в utf8, который изменил бы кодировку этого символа на двухбайтовую последовательность 0xc391 (который объясняет \xc3 вы показываете как хранящийся выше; Однако, не ясно, как второй байт 0x91 превратился в последовательность \u0192\xc2\u2018 в вашем фрагменте *).

Я подозреваю, что на самом деле данные были подвергнуты дальнейшим преобразованиям, возможно, между тем, что в настоящее время хранится, и какими-либо средствами, которые вы используете для просмотра такого хранилища. Вам было бы полезно сначала выяснить , что именно хранится в вашей базе данных:

SELECT HEX(my_column) FROM my_table WHERE ...

Как только это будет определено, вы сможете лучше понять, какие преобразования (если таковые имеются) необходимо использовать для хранения ваших данных, чтобы сделать их utf8 и какие нежелательные преобразования (если таковые имеются) происходят во время операций хранения и поиска.


* Теперь, прочитав ответ Танасиса Петса, я понял, что он понял, что вы, кажется, правильно расшифровали utf8 закодированные строки как latin1 закодировал полученные символы используя utf8 а затем декодировать эти байты как latin1 снова. Это действительно создает последовательности символов, которые вы показали, но все же необходимо понять, что на самом деле хранится и что происходит из-за преобразований во время поиска.

Попробуй это:

print str.encode('cp1252').decode('utf-8').encode('cp1252').decode('utf-8')

пример использования ipython:

In [49]: a=u'Teresa de Jes\xc3\u0192\xc2\xbas Galicia G\xc3\u0192\xc2\xb3mez'

In [50]: a=u'Teresa de Jes\xc3\u0192\xc2\xbas Galicia G\xc3\u0192\xc2\xb3mez'

In [51]: print a
Teresa de Jesús Galicia Gómez

In [52]: print a.encode('cp1252').decode('utf-8').encode('cp1252').decode('utf-8')
Teresa de Jesús Galicia Gómez

Это "неправильно закодированный" utf-8..

Другие вопросы по тегам