31

我在 Python 中工作,想以 Unicode 格式读取用户输入(从命令行),即 Unicode 等价于raw_input?

另外,我想测试 Unicode 字符串的相等性,看起来标准==不起作用。

4

4 回答 4

54

raw_input()返回由操作系统或 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

不过,如果您向我们提供更多信息,我们或许可以为您提供更多帮助。

于 2009-01-25T10:25:54.470 回答
16

它应该工作。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
日本語 Ελληνικά

至于比较 unicode 字符串:你能发布一个比较不起作用的例子吗?

于 2009-01-25T02:38:34.070 回答
4

我不太确定,您所说的“Unicode 格式”是指哪种格式,有几种。UTF-8?UTF-16?在任何情况下,您都应该能够读取普通字符串,raw_input然后使用 stringsdecode方法对其进行解码:

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

如果您有不同的输入编码,只需使用“utf-16”或其他任何东西而不是“utf-8”。另请参阅编解码器模块文档以了解不同类型的编码。

然后比较应该可以正常工作==。如果您有包含特殊字符的字符串文字,您应该在它们前面加上“u”以将它们标记为 unicode:

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

如果您想再次输出这些字符串,您可能希望以所需的编码再次对它们进行编码:

print decoded.encode("utf-8")
于 2009-01-25T02:42:49.723 回答
1

在一般情况下,可能无法比较 unicode 字符串。问题是有几种方法可以组成相同的字符。一个简单的例子是重音罗马字符。尽管基本上所有常用的重音字符都有代码点,但由非重音基本字母和非间距重音组成它们也是正确的。这个问题在许多非罗马字母表中更为重要。

于 2009-01-25T03:20:14.640 回答