You're viewing all posts tagged with unicode

Преобразование строк из/в Unicode

В дополнение к посту о funny characters.

Преобразование utf-8 в cp866 (в ASCII кодировку)

    >>> u'ы'.encode('cp866')
    '\xeb'

Преобразование cp866 в utf-8

    >>> 'ы'.decode('cp866')
    u'\u044b'

decode - декодирует последовательность байтов в юникод, encode - кодирует юникод в последовательность байтов. Последовательность байтов всегда должна интерпретироваться с учетом кодировки - в примере получаются последовательности байтов в кодировке cp866. :)

PS. А в Python 3 концепция работы с юникодом круче, как обещает документация :)

Cтрока (str) - всегда UTF-8, то есть действительно строка, в универсальной кодировке. А все остальное - последовательности байт bytes, про которые нужно знать, в какой они кодировке, если нужно их перевести в строку.

Опасаться funny characters

Предыстория

Во время написания iКучи я столкнулся с несовершенством мира. У меня появилась такая задача: по ссылке узнать title страницы. Теоретически, задача не сложная, но проявились нюансы, связанные с кодировками.

Чтобы сразу проверять работу парсера, я тестировал все в консоли. И иногда print вылетал с UnicodeEncodeError. Это явление известно как funny characters.

Пример

  • символ ‘ы’ имеет код U+044B
  • символ ‘©’ имеет код U+00A9
    >>> a = u'ы'
    >>> a
    u'\u044b'
    >>> b = u'\u00a9'
    >>> b
    u'\xa9'

Пробуем напечатать:

    >>> print a
    ы
    >>> print b
    ...
    UnicodeEncodeError: 'charmap' codec can't encode character u'\xa9' in position 0: character maps to <undefined>
    >>>

Пробуем сложить сроки и записать в файл:

    >>> f = open('test.txt', 'w')
    >>> f.write((a + b).encode('utf-8'))
    >>> f.close()

Работает!

Выводы

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

Вот здесь предлагается “вычищать” эти символы из текста: http://code.activestate.com/recipes/546517-accent2htmlcodepy-convert-accents-and-special-char

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

Почитать для знания

http://www.joelonsoftware.com/articles/Unicode.html http://www.stereoplex.com/2009/nov/8/python-unicode-and-unicodedecodeerror/