re (Python) 中的俄语符号
Posted
技术标签:
【中文标题】re (Python) 中的俄语符号【英文标题】:Russian symbols in re (Python) 【发布时间】:2013-03-05 02:30:05 【问题描述】:我从文件中获取数据:
words = re.findall(r'[\w]+',self._from.encode('utf8'),re.U)
如果文件包含:
嗨,你好吗?
那么结果将是:
['嗨','怎么样','是','你']
但如果文件包含俄语(即西里尔符号),则:
Привет, как дела?
在这种情况下,结果是:
['\xd0', '\xd1', '\xd0', '\xd0\xb2\xd0\xb5\xd1', '\xd0\xba\xd0', '\xd0\xba', '\xd0', '\xd0\xb5\xd0', '\xd0']
为什么?什么? 我已经添加了:
sys.setdefaultencoding('utf-8')
我正在使用 python2.7 和 linux ubuntu。
答案:
words = re.findall(r'[\w]+',self._from.decode('utf8'),re.U)
print u" ".join(words)
【问题讨论】:
【参考方案1】:带Ё字母的俄语字母解决方案(不包括在А-Я范围内)
import re
text = 'Ё-моё Привет! 2121 как дела?'
re.findall(r'[А-яЁё]+', text)
# => ['Ё', 'моё', 'Привет', 'как', 'дела']
【讨论】:
【参考方案2】:请参阅 UTF Cyrillic 块以精确定义正则表达式:
https://en.wikipedia.org/wiki/Cyrillic_(Unicode_block) https://en.wikipedia.org/wiki/Cyrillic_script_in_Unicode大多数代码点都在一个范围内,但有些不在:
re.compile('[А-Яа-яЁё]+')
re.fullmatch("[А-Яа-яЁё ]+", "Ёжик в тумане")
此外,您可能还需要包含 Ѣ ѣ
(Ять) 或其他旧符号,具体取决于您的需要。
【讨论】:
【参考方案3】:我的解决方案:
txt = re.findall(r'[А-я]+', data)
А-я - 俄语字母
【讨论】:
【参考方案4】:要使用\w+
匹配字母数字unicode 字符,您应该将unicode
模式和unicode
文本都传递给re.findall
。
在 Python2 中:
假设您正在从文件中读取字节(不是文本),您应该对字节进行解码以获得unicode
:
uni = 'Привет, как дела?'.decode('utf-8')
ur'(?u)\w+'
是 raw unicode literal。
即使这里没有必要,使用原始 unicode/string 文字
正则表达式模式通常是一种很好的做法——它可以让你避免
某些字符前需要双反斜杠,例如\s
。
正则表达式模式ur'(?u)\w+'
bakes-in the Unicode flag 告诉re.findall
使\w
依赖于Unicode 字符属性数据库。
import re
uni = 'Привет, как дела?'.decode('utf-8')
print(re.findall(ur'(?u)\w+', uni))
产生一个包含 3 个 unicode “单词”的列表:
[u'\u041f\u0440\u0438\u0432\u0435\u0442',
u'\u043a\u0430\u043a',
u'\u0434\u0435\u043b\u0430']
在 Python3 中:
大体原理是一样的,除了what were unicode
s in
Python2 are now str
s in Python3,不再尝试
两者之间自动转换。所以,再次假设你是
从文件中读取字节(不是文本),您应该将字节解码为
获取str
,并使用str
正则表达式模式:
import re
uni = b'\xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82, \xd0\xba\xd0\xb0\xd0\xba \xd0\xb4\xd0\xb5\xd0\xbb\xd0\xb0?'.decode('utf')
print(re.findall(r'(?u)\w+', uni))
产量
['Привет', 'как', 'дела']
【讨论】:
【参考方案5】:您正在获取一个已经是 unicode 的字符串并将其编码为 unicode 如果你省略你得到的编码部分:
line = u"Привет, как дела?"
words = re.findall(r'[\w]+',line ,re.U)
# words = [u'\u041f\u0440\u0438\u0432\u0435\u0442', u'\u043a\u0430\u043a', u'\u0434\u0435\u043b\u0430']
print words[0]
# prints Привет
【讨论】:
【参考方案6】:如果self._from
是unicode
字符串,则应将其直接传递给re.findall
(带有re.U
标志)。如果是 utf8 编码的str
字符串,则需要将decode
转换为unicode
字符串。您不应将非 ascii str
字符串传递给 re
。
【讨论】:
以上是关于re (Python) 中的俄语符号的主要内容,如果未能解决你的问题,请参考以下文章
带有俄语语言的 Grails 2.4 中的 UTF-8 问题