Python re.sub()后的字符集错误

Python re.sub()后的字符集错误,python,regex,python-2.7,Python,Regex,Python 2.7,我有这个密码 import chardet, re content = "Бланк свидетельства о допуске." print content print chardet.detect(content) content = re.sub(u"(?i)[^-0-9a-zа-яё«»\&\;\/\<\>\.,\s\(\)\*:!\?]", "", content) print content print chardet.detect(content

我有这个密码

import chardet, re    

content = "Бланк свидетельства о допуске."
print content
print chardet.detect(content)
content = re.sub(u"(?i)[^-0-9a-zа-яё«»\&\;\/\<\>\.,\s\(\)\*:!\?]", "", content)
print content
print chardet.detect(content)
我做错了什么?如何在
re.sub()之后获取uft-8字符串?
(Python 2.7,
#编码:utf-8
,文件格式为utf-8,IDE Pycharm)

谢谢。

您的输入是UTF-8:

>>> content
'\xd0\x91\xd0\xbb\xd0\xb0\xd0\xbd\xd0\xba \xd1\x81\xd0\xb2\xd0\xb8\xd0\xb4\xd0\xb5\xd1\x82\xd0\xb5\xd0\xbb\xd1\x8c\xd1\x81\xd1\x82\xd0\xb2\xd0\xb0 \xd0\xbe \xd0\xb4\xd0\xbe\xd0\xbf\xd1\x83\xd1\x81\xd0\xba\xd0\xb5.'
但您使用的是unicode正则表达式。表达式直接与 UTF-8输入的原始字节

在所有这些字节中,只有空格、句号和
\xbb
字节(作为
»
字符)未被删除。其余的单个字节将被删除,因为它们不属于负字符类
[^…]

正确使用Unicode(首先将
内容
解码为Unicode)可以:

>>re.sub(u)(?i)[^-0-9a-zа-аё«»&\;\/\,\s\(\)\*:!\?],“”,content.decode('utf8'))
u'\u043b\u0430\u043d\u043a\u0441\u0432\u0438\u0434\u0435\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u0430\u043e\u0434\u043e\u043f\u0443\u0441\u043a\u0435'
>>>打印参考文件(u“(?i)[^-0-9a-zа-1105;«»»和»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
ланк свидетельства о допуске.
另一种方法是为正则表达式使用原始字节字符串,并匹配字节组合。计算出什么UTF-8字节和范围是有效的是非常棘手的。您需要完全理解如何将负字符类转换为允许通过相同字节组合的一组正匹配。这是而不是对于心脏虚弱的人来说。

这就是(我认为)你试图实现的目标(为了清晰起见,我简化了regexp):

注意要点:

  • 主题是unicode
  • 表达式是unicode
  • 表达式使用unicode标志
    (?u)
    使箱子折叠工作
此外,对于重要的unicode工作,我推荐使用该模块,它提供了出色且几乎完全的unicode支持。考虑:

# drop everything except Cyrillic and spaces 
import regex
content = regex.sub(u'[^\p{Cyrillic}\p{Zs}]', '', content) 
虽然
re.UNICODE
只会改变
\w
和朋友,但在我的测试中,它也会影响大小写折叠(
re.IGNORECASE
):


这要么是一个未记录的特性,要么是一个文档问题。

您试图在原始字节上使用正则表达式?您在这里操作的是字节,而不是字符,输入字符每个由2个字节组成。我如何获得UTF-8?期望的输出是什么?请检查此答案,以获取指向“每个软件开发人员绝对、肯定必须了解Unicode和字符集的绝对最小值”的指针抱歉,我知道您的表达式本身是unicode。您不应将这些内容混用。
re.IGNORECASE
的文档说明它不受语言环境的影响。
re.UNICODE
标志被记录为仅更改字符类(
\w
\w
\s
\s
等)。感谢
regex
模块。@thg435:很有趣,谢谢确认!听起来文档需要更新。
>>> re.sub(u"(?i)[^-0-9a-zа-яё«»\&\;\/\<\>\.,\s\(\)\*:!\?]", "", content.decode('utf8'))
u'\u043b\u0430\u043d\u043a \u0441\u0432\u0438\u0434\u0435\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u0430 \u043e \u0434\u043e\u043f\u0443\u0441\u043a\u0435.'
>>> print re.sub(u"(?i)[^-0-9a-zа-яё«»\&\;\/\<\>\.,\s\(\)\*:!\?]", "", content.decode('utf8'))
ланк свидетельства о допуске.
#coding=utf8
import re    
content = u"Бланк XYZ свидетельства о ???допуске."
content = re.sub(u"(?iu)[^а-яё]", ".", content)
print content.encode('utf8') # Бланк.....свидетельства.о....допуске.
# drop everything except Cyrillic and spaces 
import regex
content = regex.sub(u'[^\p{Cyrillic}\p{Zs}]', '', content) 
Python 2.7.2+ (default, Oct  4 2011, 20:06:09) 
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>> src = u'Σσ Φφ Γγ'
>>> src
u'\u03a3\u03c3 \u03a6\u03c6 \u0393\u03b3'
>>> re.sub(ur'(?i)[α-ώ]', '-', src)
u'\u03a3- \u03a6- \u0393-'
>>> re.sub(ur'(?iu)[α-ώ]', '-', src)
u'-- -- --'