Проверить строку, если это Unicode, какой стандарт UTF и получить ее длину в байтах?

Мне нужно проверить, является ли строка Unicode, а затем, если это UTF-8. После этого получите длину строки в байтах, включая BOM, если она когда-либо используется. Как это можно сделать в Python?

Также в дидактических целях, как выглядит представление списка байтов строки UTF-8? Мне любопытно, как строка UTF-8 представлена ​​​​в Python.

Последнее редактирование: pprint делает это довольно хорошо.


person Eduard Florinescu    schedule 21.08.2012    source источник
comment
В каких кодировках вы ожидаете, что строка будет?   -  person ecatmur    schedule 21.08.2012
comment
Мне нужно, чтобы они были UTF8 и ASCII!   -  person Eduard Florinescu    schedule 21.08.2012
comment
Если строка ASCII, то она также в UTF-8. Что вы на самом деле пытаетесь здесь сделать?   -  person ecatmur    schedule 21.08.2012
comment
Я получаю относительный путь к файлу в zip-архиве с библиотекой zipfile, и мне нужно проверить, соответствует ли он этому стандарту: w3.org/TR/widgets/#zip-относительные-пути   -  person Eduard Florinescu    schedule 21.08.2012
comment
В этом случае все, что вам нужно, это проверить, является ли это UTF-8.   -  person ecatmur    schedule 21.08.2012
comment
@ecatmur, а если в нем только символы ASCII? Как я могу это знать?   -  person Eduard Florinescu    schedule 21.08.2012
comment
Вы можете написать string.decode('ascii'), но в этом нет особого смысла, так как ASCII является допустимым UTF-8.   -  person ecatmur    schedule 21.08.2012


Ответы (3)


try:
    string.decode('utf-8')
    print "string is UTF-8, length %d bytes" % len(string)
except UnicodeError:
    print "string is not UTF-8"

В Python 2 str — это последовательность байтов, а unicode — это последовательность символов. Вы используете str.decode для декодирования последовательности байтов в unicode и unicode.encode для кодирования последовательности символов в str. Так, например, u"é" — это строка Юникода, содержащая один символ U+00E9, и ее также можно записать как u"\xe9"; кодирование в UTF-8 дает последовательность байтов "\xc3\xa9".

В Python 3 это изменено; bytes — это последовательность байтов, а str — это последовательность символов.

person ecatmur    schedule 21.08.2012
comment
Я также хочу видеть, является ли строка ASCII или Unicode, ваш код не допускает, чтобы строка была другим типом Unicode UTF? - person Eduard Florinescu; 21.08.2012
comment
@EduardFlorinescu для других кодировок передайте другую кодировку в string.decode. - person ecatmur; 21.08.2012
comment
Я получаю эту ошибку на string.decode('utf-8') UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-5: ordinal not in range(128) - person Eduard Florinescu; 21.08.2012
comment
@EduardFlorinescu в этом случае string уже является объектом unicode, поэтому это последовательность символов, а не байтов. Вы можете проверить, сколько байтов использует его представление UTF-8, с помощью len(string.encode('utf-8')). - person ecatmur; 21.08.2012
comment
Кажется, что объект zipfile библиотеки Zipinfo имеет скрытое поле: orig_filename другое, чем filename, которое уже является юникодом, который содержит исходную кодировку имени файла в моем случае UTF8. - person Eduard Florinescu; 21.08.2012

Чтобы проверить, если Unicode

>>>a = u'F'
>>>isinstance(a, unicode)
True

Чтобы проверить, является ли это UTF-8 или ASCII

>>>import chardet
>>>encoding = chardet.detect('AA')
>>>encoding['encoding']
'ascii'
person Rakesh    schedule 21.08.2012
comment
С экземпляром я получаю много этого: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal , а со вторым, если я ставлю вместо ('AA'), я получаю IndexError: tuple index out of range - person Eduard Florinescu; 21.08.2012

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

Чтобы узнать о Unicode и механизме кодирования/декодирования Python, начните с здесь. Чтобы получить длину в байтах строки Unicode, закодированной в utf-8, вы можете сделать:

print len(my_unicode_string.encode('utf-8'))

Ваш вопрос помечен как python-2.5, но имейте в виду, что это несколько меняется в Python 3+.

person thebjorn    schedule 21.08.2012