Следующий 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'
который устраняет мою проблему. Кто-то может объяснить мне, что точно происходит?
Похоже, вы запутались в кодировках. Кажется вероятным, что на самом деле вам нужно 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'
Теперь она в правильном формате.
Однако вместо этого, если это возможно, вы должны попытаться выяснить, почему данные были неправильно закодированы в первую очередь, и устранить эту проблему.
Похоже,
str(value_uni)
должно работать ... по крайней мере, когда я попробовал.
РЕДАКТИРОВАТЬ : Оказывается, это работает только потому, что в моей системе кодировка по умолчанию, насколько я могу судить, ISO-8859-1 (Latin-1). Поэтому для независимой от платформы версии попробуйте
value_uni.encode('latin1')
Упрощенное объяснение. Тип str способен хранить только символы из диапазона 0-255. Если вы хотите хранить юникод (который может содержать символы из гораздо более широкого диапазона) в str, вам сначала нужно закодировать юникод в формат, подходящий для str, например UTF-8.
Для этого вызовите метод encode на вашем объекте str и в качестве аргумента укажите желаемую кодировку, например this_is_str = value_uni.encode('utf-8')
.
Вы можете прочитать более подробную и глубокую (и не зависящую от языка) статью о работе с Unicode здесь: Абсолютный минимум, который должен знать каждый разработчик программного обеспечения о Unicode и наборах символов (никаких отговорок!).
Еще одна отличная статья (на этот раз специфичная для Python): Unicode HOWTO
value_uni.encode ('utf8')
или в любой другой кодировке, которая вам нужна.
ОП не конвертирует ни в ascii, ни в utf-8. Поэтому предложенные методы encode
не работают. Попробуйте следующее:
v = u'Andr\xc3\xa9'
s = ''.join(map(lambda x: chr(ord(x)),v))
Вызов chr(ord(x))
получает числовое значение символа юникода (которое лучше уместить в один байт для вашего приложения), а вызов ''.join
- это идиома, которая преобразует список ints обратно в обычную строку. Несомненно, существует более элегантный способ.
Вы спросили (в комментарии) "" "Это то, что меня озадачивает. Как все прошло от оригинального акцента к тому, что есть сейчас? Когда вы скажем, двойное кодирование с 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')
, как предлагается в различных ответы на ваш вопрос.
Если у вас 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é