Как я преобразовываю unicode в строку на уровне Python?

Следующий unicode и строка могут существовать самостоятельно, если определено явно:

>>> value_str='Andr\xc3\xa9'
>>> value_uni=u'Andr\xc3\xa9'

Если я только имею u'Andr\xc3\xa9' присвоенный переменной как вышеупомянутый, как я преобразовываю его в 'Andr\xc3\xa9' в Python 2.5 или 2.6?

Править:

Я сделал следующее:

>>> value_uni.encode('latin-1')
'Andr\xc3\xa9'

который устраняет мою проблему. Кто-то может объяснить мне, что точно происходит?

13
задан Thierry Lam 6 May 2010 в 17:42
поделиться

7 ответов

Похоже, вы запутались в кодировках. Кажется вероятным, что на самом деле вам нужно u'Andr\xe9', что эквивалентно 'André'.

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

>>> ''.join(chr(ord(c)) for c in u'Andr\xc3\xa9')
'Andr\xc3\xa9'

Затем декодируйте ее правильно:

>>> ''.join(chr(ord(c)) for c in u'Andr\xc3\xa9').decode('utf8')
u'Andr\xe9'    

Теперь она в правильном формате.

Однако вместо этого, если это возможно, вы должны попытаться выяснить, почему данные были неправильно закодированы в первую очередь, и устранить эту проблему.

15
ответ дан 1 December 2019 в 21:24
поделиться

Похоже,

str(value_uni)

должно работать ... по крайней мере, когда я попробовал.

РЕДАКТИРОВАТЬ : Оказывается, это работает только потому, что в моей системе кодировка по умолчанию, насколько я могу судить, ISO-8859-1 (Latin-1). Поэтому для независимой от платформы версии попробуйте

value_uni.encode('latin1')
-1
ответ дан 1 December 2019 в 21:24
поделиться

Упрощенное объяснение. Тип str способен хранить только символы из диапазона 0-255. Если вы хотите хранить юникод (который может содержать символы из гораздо более широкого диапазона) в str, вам сначала нужно закодировать юникод в формат, подходящий для str, например UTF-8.

Для этого вызовите метод encode на вашем объекте str и в качестве аргумента укажите желаемую кодировку, например this_is_str = value_uni.encode('utf-8').

Вы можете прочитать более подробную и глубокую (и не зависящую от языка) статью о работе с Unicode здесь: Абсолютный минимум, который должен знать каждый разработчик программного обеспечения о Unicode и наборах символов (никаких отговорок!).

Еще одна отличная статья (на этот раз специфичная для Python): Unicode HOWTO

0
ответ дан 1 December 2019 в 21:24
поделиться

value_uni.encode ('utf8') или в любой другой кодировке, которая вам нужна.

См. http://docs.python.org/library/stdtypes.html#str.encode

4
ответ дан 1 December 2019 в 21:24
поделиться

ОП не конвертирует ни в ascii, ни в utf-8. Поэтому предложенные методы encode не работают. Попробуйте следующее:

v = u'Andr\xc3\xa9'
s = ''.join(map(lambda x: chr(ord(x)),v))

Вызов chr(ord(x)) получает числовое значение символа юникода (которое лучше уместить в один байт для вашего приложения), а вызов ''.join - это идиома, которая преобразует список ints обратно в обычную строку. Несомненно, существует более элегантный способ.

1
ответ дан 1 December 2019 в 21:24
поделиться

Вы спросили (в комментарии) "" "Это то, что меня озадачивает. Как все прошло от оригинального акцента к тому, что есть сейчас? Когда вы скажем, двойное кодирование с utf8 и latin1, это всего 3 кодировки (2 utf8 + 1 latin1)? Каков порядок кодирования от исходного состояния до текущего? "" "

В ответе Марка Байерса , он говорит "" "похоже, у вас есть кодировка UTF-8, которая была неправильно декодирована" "". Вы приняли его ответ. Но вы все еще недоумеваете? Хорошо, вот подробное описание:

Примечание: все строки будут отображаться с использованием (неявно) repr () . unicodedata.name () будет использоваться для проверки содержимого.Таким образом, вариации в кодировке консоли не могут запутать интерпретацию строк.

Начальное состояние: у вас есть объект Unicode с именем u1. Он содержит символ e-excit:

>>> u1 = u'\xe9'
>>> import unicodedata as ucd
>>> ucd.name(u1)
'LATIN SMALL LETTER E WITH ACUTE'

Вы кодируете u1 как UTF-8 и называете результат s:

>>> s = u1.encode('utf8')
>>> s
'\xc3\xa9'

Вы декодируете s, используя latin1 - НЕПРАВИЛЬНО; s был закодирован с использованием utf8, а НЕ latin1. Результат - бессмысленная чушь.

>>> u2 = s.decode('latin1')
>>> u2
u'\xc3\xa9'
>>> ucd.name(u2[0]); ucd.name(u2[1])
'LATIN CAPITAL LETTER A WITH TILDE'
'COPYRIGHT SIGN'
>>>

Пожалуйста, поймите: unicode_object.encode ('x'). Decode ('y) , когда x! = Y обычно [см. Примечание ниже], бессмысленно; он вызовет исключение, если вам повезет; если вам не повезет, он будет тихо создавать тарабарщину. Также, пожалуйста, поймите, что тихое создание тарабарщины не является ошибкой - не существует общего способа, которым Python (или любой другой язык) мог бы обнаружить, что была совершена бессмыслица. Это особенно актуально, когда задействован latin1, потому что все 256 кодовых точек сопоставляются от 1 до 1 с первыми 256 кодовыми точками Unicode, поэтому невозможно получить UnicodeDecodeError из str_object.decode ('latin1').

Конечно, ненормально (можно надеяться, что это ненормально) вам может потребоваться отменить такую ​​ерунду, выполнив gibberish_unicode_object.encode ('y'). Decode ('x') , как предлагается в различных ответы на ваш вопрос.

5
ответ дан 1 December 2019 в 21:24
поделиться

Если у вас u'Andr\xc3\xa9', то это строка Unicode, которая была декодирована из байтовой строки с неправильной кодировкой. Правильной кодировкой является UTF-8. Чтобы преобразовать ее обратно в байтовую строку и правильно декодировать, можно воспользоваться приемом, который вы обнаружили. Первые 256 кодовых точек Юникода соответствуют кодировке ISO-8859-1 (псевдоним latin1) в соотношении 1:1. Итак:

>>> u'Andr\xc3\xa9'.encode('latin1')
'Andr\xc3\xa9'

Теперь это байтовая строка, которая может быть правильно декодирована с помощью utf8:

>>> 'Andr\xc3\xa9'.decode('utf8')
u'Andr\xe9'
>>> print 'Andr\xc3\xa9'.decode('utf8')
André

За один шаг:

>>> print u'Andr\xc3\xa9'.encode('latin1').decode('utf8')
André
2
ответ дан 1 December 2019 в 21:24
поделиться
Другие вопросы по тегам:

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