Python中的正则表达式中的俄语符号

14 投票
6 回答
21869 浏览
提问于 2025-04-17 19:18

我从一个文件中获取数据:

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)

6 个回答

2

查看UTF西里尔字母块以准确定义正则表达式:

大部分字符代码在一个范围内,但有些不在这个范围内:

re.compile('[А-Яа-яЁё]+')

re.fullmatch("[А-Яа-яЁё ]+", "Ёжик в тумане")

另外,根据你的需求,你可能还想包括 Ѣ ѣ(也叫“Ять”)或其他一些旧符号。

4

我的解决方案:

txt = re.findall(r'[А-я]+', data)

А到я - 这是俄语字母表的字母

10

要使用 \w+ 来匹配字母数字的 unicode 字符,你需要同时给 re.findall 提供一个 unicode 模式和 unicode 文本。

  • 在 Python2 中:

    假设你是从文件中读取字节(而不是文本),你需要先将这些字节解码成 unicode

    uni = 'Привет, как дела?'.decode('utf-8')
    

    ur'(?u)\w+' 是一个 原始的 unicode 字面量。虽然在这里并不是必须的,但通常使用原始的 unicode/字符串字面量来写正则表达式是个好习惯——这样可以避免在某些字符前面需要加双反斜杠,比如 \s

    这个正则表达式模式 ur'(?u)\w+' 内置了 Unicode 标志,这告诉 re.findall 要根据 Unicode 字符属性数据库来处理 \w

    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 中:

    原则上是一样的,只是 在 Python2 中的 unicode 现在变成了 Python3 中的 str,而且不再自动进行这两者之间的转换。所以,假设你还是从文件中读取字节(而不是文本),你需要将字节解码成 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))
    

    结果是

    ['Привет', 'как', 'дела']
    

撰写回答