Работа с дурацкими кодировками в Python - PullRequest
3 голосов
/ 07 июня 2010

У меня есть скрипт Python, который извлекает данные из многих источников (базы данных, файлы и т. Д.). Предположительно, все строки в кодировке Unicode, но в итоге я получаю любые изменения в следующей теме (как возвращено repr()):

u'D\\xc3\\xa9cor'
u'D\xc3\xa9cor'
'D\\xc3\\xa9cor'
'D\xc3\xa9cor'

Есть ли надежный способ взять любые четыре из вышеперечисленных строк и вернуть правильную строку юникода?

u'D\xe9cor' # --> Décor

Единственный способ, о котором я могу думать сейчас, - это eval(), replace() и глубокий жгучий стыд, который никогда не смоется.

Ответы [ 3 ]

4 голосов
/ 07 июня 2010

Это просто UTF-8 data . Используйте .decode, чтобы преобразовать его в unicode.

>>> 'D\xc3\xa9cor'.decode('utf-8')
u'D\xe9cor'

Вы можете выполнить дополнительное декодирование escape-строки для случая 'D\\xc3\\xa9cor'.

>>> 'D\xc3\xa9cor'.decode('string-escape').decode('utf-8')
u'D\xe9cor'
>>> 'D\\xc3\\xa9cor'.decode('string-escape').decode('utf-8')
u'D\xe9cor'
>>> u'D\\xc3\\xa9cor'.decode('string-escape').decode('utf-8')
u'D\xe9cor'

Чтобы справиться и со вторым случаем, вам необходимо определить, является ли ввод unicode, и преобразовать его в str сначала.

>>> def conv(s):
...   if isinstance(s, unicode):
...     s = s.encode('iso-8859-1')
...   return s.decode('string-escape').decode('utf-8')
... 
>>> map(conv, [u'D\\xc3\\xa9cor', u'D\xc3\xa9cor', 'D\\xc3\\xa9cor', 'D\xc3\xa9cor'])
[u'D\xe9cor', u'D\xe9cor', u'D\xe9cor', u'D\xe9cor']
2 голосов
/ 07 июня 2010

Напишите адаптеры, которые знают, какие преобразования должны применяться к их источникам.

>>> 'D\xc3\xa9cor'.decode('utf-8')
u'D\xe9cor'
>>> 'D\\xc3\\xa9cor'.decode('string-escape').decode('utf-8')
u'D\xe9cor'
1 голос
/ 07 июня 2010

Вот решение, к которому я пришел, прежде чем увидел правильное, более краткое решение KennyTM:

def ensure_unicode(string):
    try:
        string = string.decode('string-escape').decode('string-escape')
    except UnicodeEncodeError:
        string = string.encode('raw_unicode_escape')

    return unicode(string, 'utf-8')
...