【问题标题】:How to find all capital and lower case occurrences of unicode character using regex and re.sub in Python?如何在 Python 中使用 regex 和 re.sub 查找所有大写和小写的 unicode 字符?
【发布时间】:2014-05-18 22:13:05
【问题描述】:

这是我在 django 视图中的代码(有意简化)(Python 2.7):

# -*- coding: utf-8 -*-
from django.shortcuts import render
import re

def index(request):
    found_verses = [] 
    pattern = re.compile('ю')

    with open('d.txt', 'r') as doc:
        for line in doc:

            found = pattern.search(line)

            if found:
                modified_line = pattern.sub('!'+'\g<0>'+'!',line)
                found_verses.append(modified_line)

context = {'found_verses': found_verses}
return render(request, 'myapp/index.html', context)

d.txt(也是 utf-8)包含这一行(特意简化):

1. Я сказал Юлию одному.

上面的内容在渲染时给了我预期的结果:

1. Я сказал Юли!ю! одному.

当我改成大写字母pattern = re.compile('Ю')时,它也给了我预期的结果:

1. Я сказал !Ю!лию одному.

但是当我更改为pattern = re.compile('[юЮ]')pattern = re.compile('[Юю]')pattern = re.compile('[ю]')pattern = re.compile('[Ю]') 组时,它什么也没给我。我想要得到的是:

1. Я сказал !Ю!ли!ю! одному.

请帮助我得到这个结果。我已经挣扎了一天多,尝试了不同的配置,例如pattern = re.compile('[юЮ]', re.UNICODE)pattern = re.compile('ю', re.UNICODE|re.I)this 以及无数其他配置,但都是徒劳的。

【问题讨论】:

  • 很难判断您何时使用实际字符...您可以添加您在打印时看到的 repr 是什么吗?例如 print repr(line)
  • @JoranBeasley,我明白了:'1. \xd0\xaf \xd1\x81\xd0\xba\xd0\xb0\xd0\xb7\xd0\xb0\xd0\xbb \xd0\xae\xd0\xbb\xd0\xb8\xd1\x8e \xd0\xbe\xd0\xb4\xd0\xbd\xd0\xbe\xd0\xbc\xd1\x83.'
  • 我认为你只需要用 utf8 line = line.decode("utf8") 将其解码为 un​​icode,然后我认为 wi 就可以了

标签: python regex django python-2.7 unicode


【解决方案1】:

问题可能是您使用的是常规字符串,而不是 unicode 字符串。 re 库需要知道如何处理 RE 中的字节。试试

re.compile(u'ю')

(请注意,@Ignacio 在他的回答中就是这样做的)。

【讨论】:

  • 谢谢,亚历克西斯,但是u 不是唯一的问题。显然我需要io 或显式解码line。但是,为什么我们需要在顶部使用# -*- coding: utf-8 -*-...即使问题解决了,但我无法完全理解它。您在顶部声明 utf-8,打开一个 utf-8 文件,但随后您必须将其解码为 utf-8,并且您需要使用 u 进行搜索。这让我很困惑。
  • 有点奇怪,是真的。主要思想是unicode是unicode,但utf-8只是一种编码。所以你不解码为 utf-8,你 encode 到它或解码 from 它。 Ignacio 的代码是 utf-8 编码解码。至于脚本顶部的声明,它仅涵盖阅读脚本本身。当您的脚本从文件中读取时,可能是另一种编码(毕竟,一个脚本可以读取不同编码的多个文件)。所以需要正确读取文件,并且需要正确创建搜索字符串(在脚本中)。
【解决方案2】:

只是猜测,但试试这个

with open('d.txt', 'rb') as doc: #I guess you probably dont need the b flag for utf8 but meh
        for line in doc:
            line = line.decode("utf8")
             ...

【讨论】:

  • 谢谢,乔丹。仅当我将 u 添加到 pattern = re.compile(u'[Юю]') 时,您的代码才有效。抱歉,必须把它交给@Ignacio,因为他的回答是按原样工作的。但是,你能解决吗,所以我不使用pattern = re.compile(u'[Юю]'),而是使用pattern = re.compile(u'ю', re.I)。据我了解,这些应该是等价的,但是后者没有突出显示大写字母。
【解决方案3】:

Use unicodes.

with io.open('d.txt', 'r', encoding='utf-8') as doc:
   ...

...

pattern = re.compile(u'[юЮ]', re.UNICODE)

【讨论】:

  • 谢谢,乔丹!有用!但有趣的是,即使没有encoding='utf-8're.UNICODE,它也能正常工作。我很困惑。所以我猜oi 有一些魔力。你能不能解决,所以我不使用pattern = re.compile(u'[Юю]'),而是使用pattern = re.compile(u'ю', re.I)。据我了解,这些应该是等价的,但是后者不会突出显示大写字母(反之,如果我使用大写字母,则不会突出显示小写字母)。换句话说,我如何将re.I 与 unicode 一起使用?
  • 顺便说一句,我确实看过幻灯片,但它仍然不适合我愚蠢的脑袋。请阅读我对亚历克西斯的评论。
  • 您可能需要使用locale 正确设置区域设置;我从来没有处理过西里尔字母,所以我不能肯定。 coding 标头仅适用于代码中的文字。而且您不会将解码为 UTF-8,而是将 UTF-8 解码为unicode
猜你喜欢
  • 1970-01-01
  • 2015-03-15
  • 1970-01-01
  • 2021-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-13
  • 2011-02-15
相关资源
最近更新 更多