web-dev-qa-db-ja.com

PythonでUnicode入力を読み取り、Unicode文字列を比較する方法は?

私はPythonで作業しており、ユーザー入力(コマンドラインから)をUnicode形式、つまりUnicodeのraw_inputに相当するもの)で読みたいと思っています。

また、Unicode文字列が等しいかどうかをテストしたいのですが、標準の==が機能しないようです。

30
alexpeter

raw_input() は、OSまたはUI機能によってエンコードされた文字列を返します。問題は、どちらがそのデコードであるかを知ることです。次のことを試してみてください。

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

ほとんどの場合、これは正しく機能するはずです。

あなたを助けるために、ユニコード比較が機能しないことについてのより多くのデータが必要です。ただし、正規化の問題かもしれません。以下を検討してください。

_>>> 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
_

さらに情報を提供していただければ、さらにサポートできる可能性があります。

54
tzot

うまくいくはずです。 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's not utf-8
>>> uni
u'\u65e5\u672c\u8a9e \u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac'

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

ユニコード文字列の比較について:比較が機能しない例を投稿できますか?

16
dF.

「Unicode形式」とはどの形式を意味するのか、よくわかりません。いくつかあります。 UTF-8? UTF-16?いずれの場合でも、raw_inputを使用して通常の文字列を読み取り、文字列decodeメソッドを使用してそれをデコードできます。

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

別の入力エンコーディングがある場合は、「utf-8」の代わりに「utf-16」などを使用してください。さまざまな種類のエンコーディングについては コーデックモジュールのドキュメント も参照してください。

次に、==と比較すると問題なく動作します。特殊文字を含む文字列リテラルがある場合は、それらに「u」をプレフィックスとして付けて、ユニコードとしてマークする必要があります。

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

そして、これらの文字列を再び出力したい場合は、おそらく希望のエンコーディングで再度エンコードしたいでしょう:

print decoded.encode("utf-8")
4
sth

一般的なケースでは、Unicode文字列を比較することはおそらく不可能です。問題は、同じ文字を構成する方法がいくつかあることです。簡単な例はアクセント付きのローマ字です。基本的に一般的に使用されるアクセント付き文字のすべてにコードポイントがありますが、アクセントなしのベース文字と非スペースアクセントからそれらを作成することも正しいです。この問題は、多くの非ローマ字アルファベットでより重要です。

1
TokenMacGuy