Подтвердить что ты не робот

Как прочитать ввод Unicode и сравнить строки Unicode в Python?

Я работаю в Python и хотел бы прочитать пользовательский ввод (из командной строки) в формате Unicode, то есть Unicode эквивалентно raw_input?

Кроме того, я хотел бы проверить строки Unicode на равенство, и похоже, что стандарт == не работает.

4b9b3361

Ответ 1

raw_input() возвращает строки, закодированные средствами OS или UI. Трудность заключается в знании того, что такое декодирование. Вы можете попробовать следующее:

import sys, locale
text= raw_input().decode(sys.stdin.encoding or locale.getpreferredencoding(True))

который должен работать правильно в большинстве случаев.

Нам нужно больше данных о неработающих Unicode-сравнениях, чтобы помочь вам. Однако это может быть вопросом нормализации. Рассмотрим следующее:

>>> a1= u'\xeatre'
>>> a2= u'e\u0302tre'

a1 и a2 эквивалентны, но не равны:

>>> print a1, a2
être être
>>> print a1 == a2
False

Таким образом, вы можете использовать метод unicodedata.normalize():

>>> import unicodedata as ud
>>> ud.normalize('NFC', a1)
u'\xeatre'
>>> ud.normalize('NFC', a2)
u'\xeatre'
>>> ud.normalize('NFC', a1) == ud.normalize('NFC', a2)
True

Если вы дадите нам больше информации, мы можем помочь вам больше.

Ответ 2

Он должен работать. raw_input возвращает строку байта, которую вы должны декодировать, используя правильную кодировку, чтобы получить объект unicode. Например, для Python 2.5/Terminal.app/OSX для меня работает следующее:

>>> bytes = raw_input()
日本語 Ελληνικά
>>> bytes
'\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e \xce\x95\xce\xbb\xce\xbb\xce\xb7\xce\xbd\xce\xb9\xce\xba\xce\xac'

>>> uni = bytes.decode('utf-8') # substitute the encoding of your terminal if it not utf-8
>>> uni
u'\u65e5\u672c\u8a9e \u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac'

>>> print uni
日本語 Ελληνικά

Что касается сравнения строк unicode: можете ли вы опубликовать пример, в котором сравнение не работает?

Ответ 3

Я не уверен, какой формат вы подразумеваете под "Unicode format", их несколько. UTF-8? UTF-16? В любом случае вы должны иметь возможность читать обычную строку с помощью raw_input, а затем декодировать ее с помощью метода строк decode:

raw = raw_input("Please input some funny characters: ")
decoded = raw.decode("utf-8")

Если у вас есть другая входная кодировка, просто используйте "utf-16" или что-то другое вместо "utf-8". Также смотрите модули кодеков docs для разных типов кодировок.

Сравнение тогда должно отлично работать с ==. Если у вас есть строковые литералы, содержащие специальные символы, вы должны префикс их "u", чтобы пометить их как unicode:

if decoded == u"äöü":
  print "Do you speak German?"

И если вы хотите снова вывести эти строки, вы, вероятно, захотите снова закодировать их в нужной кодировке:

print decoded.encode("utf-8")

Ответ 4

В общем случае, вероятно, невозможно сравнивать строки unicode. Проблема в том, что существует несколько способов составления одних и тех же символов. Простым примером являются акцентированные римские символы. Несмотря на то, что в основном используются все используемые символы с акцентом, есть коды, также правильно их составлять из несогласованных базовых букв и акцента без интервала. Эта проблема более значительна во многих неязыковых алфавитах.