将 Unicode 字符串拆分为单词
我正在尝试把一个Unicode字符串拆分成单词(简单点说),像这样:
print re.findall(r'(?u)\w+', "раз два три")
我期待看到的是:
['раз','два','три']
但我实际得到的是:
['\xd1', '\xd0', '\xd0', '\xd0', '\xd0\xb2\xd0', '\xd1', '\xd1', '\xd0']
我哪里做错了呢?
编辑:
如果我在字符串前面加上u
:
print re.findall(r'(?u)\w+', u"раз два три")
我得到的是:
[u'\u0440\u0430\u0437', u'\u0434\u0432\u0430', u'\u0442\u0440\u0438']
编辑 2:
看来我应该先看看文档:
print re.findall(r'(?u)\w+', u"раз два три")[0].encode('utf-8')
这样会给我:
раз
不过我想确认一下,这样的方法是不是正确的呢?
1 个回答
6
其实你得到的内容在unicode的情况下是正常的。你之所以觉得不对劲,是因为你看到的是字符串的表示形式,而不是它们未转义的值。(这就是列表显示的方式。)
>>> words = [u'\u0440\u0430\u0437', u'\u0434\u0432\u0430', u'\u0442\u0440\u0438']
>>> for w in words:
... print w # This uses the terminal encoding -- _only_ utilize interactively
...
раз
два
три
>>> u'раз' == u'\u0440\u0430\u0437'
True
别忘了我提到的关于打印这些unicode字符串的事情。通常,如果你要把它们发送到屏幕、文件或者网络上,你需要手动把它们编码成正确的格式。当你使用print
时,Python会尝试使用你终端的编码,但这只有在有终端的情况下才能做到。因为你通常不知道是否有终端,所以在交互式解释器中可以依赖这个,但在其他情况下一定要明确地编码成正确的格式。
在这种简单的按空格分割的方式中,你可能根本不需要使用正则表达式,而是可以直接使用unicode.split
方法。
>>> u"раз два три".split()
[u'\u0440\u0430\u0437', u'\u0434\u0432\u0430', u'\u0442\u0440\u0438']
你给的第一个(字节字符串)例子不工作,因为re
基本上假设所有字节字符串都是ASCII格式,但你的不是。使用unicode字符串可以让你得到适合你字母表和地区的正确语义。尽可能地,文本数据应该始终使用unicode
来表示,而不是str
。