用中文内容替换后的Python \ ufffd

时间:2015-03-22 15:05:06

标签: python regex python-2.7

在我们找到this question的答案后,我们面临着下一次不寻常的替换行为:

我们的正则表达式是:

[\\((\\[{【]+(\\w+|\\s+|\\S+|\\W+)?[)\\)\\]}】]+

我们正在尝试匹配任何类型的括号内的所有内容,包括括号 原文如下:

物理化学名校考研真题详解 (理工科考研辅导系列(化学生物类))

结果是:

物�研真题详解

替换的代码是:

 delimiter = ' '
 if localization == 'CN':
        delimiter = ''
  p = re.compile(codecs.encode(unicode(regex), "utf-8"), flags=re.I)
  columnString = (p.sub(delimiter, columnString).strip()

为什么会出现 (\ ufffd)字符以及如何修复此类行为?

当我们使用正则表达式时,我们遇到了同样的问题:

(\\d*[满|元])

print repr(columnString)='\xe5\xbd\x93\xe4\xbb\xa3\xe9\xaa\xa8\xe4\xbc\xa4\xe7\xa7\x91\xe5\xa6\x99\xe6\x96\xb9(\xe7\xac\xac\xe5\x9b\x9b\xe7\x89\x88)'

print repr(regex)=u'[\\(\uff08\\[{\u3010]+(\\w+|\\s+|\\S+|\\W+)?[\uff09\\)\\]}\u3011]+'

print repr(p.pattern)='[\\(\xef\xbc\x88\\[{\xe3\x80\x90]+(\\w+|\\s+|\\S+|\\W+)?[\xef\xbc\x89\\)\\]}\xe3\x80\x91]+'

2 个答案:

答案 0 :(得分:1)

您不应该混合使用UTF-8和正则表达式。将所有文本处理为Unicode。确保首先将正则表达式和输入字符串解码unicode值:

>>> import re
>>> columnString = '\xe5\xbd\x93\xe4\xbb\xa3\xe9\xaa\xa8\xe4\xbc\xa4\xe7\xa7\x91\xe5\xa6\x99\xe6\x96\xb9(\xe7\xac\xac\xe5\x9b\x9b\xe7\x89\x88)'
>>> regex = '[\\(\xef\xbc\x88\\[{\xe3\x80\x90]+(\\w+|\\s+|\\S+|\\W+)?[\xef\xbc\x89\\)\\]}\xe3\x80\x91]+'
>>> utf8_compiled = re.compile(regex, flags=re.I)
>>> utf8_compiled.sub('', columnString)
'\xe5\xbd\x93\xe4\xbb\xa3\xe9\xaa\xa8\xe4'
>>> print utf8_compiled.sub('', columnString).decode('utf8', 'replace')
当代骨�
>>> unicode_compiled = re.compile(regex.decode('utf8'), flags=re.I | re.U)
>>> unicode_compiled.sub('', columnString.decode('utf8'))
u'\u5f53\u4ee3\u9aa8\u4f24\u79d1\u5999\u65b9'
>>> print unicode_compiled.sub('', columnString.decode('utf8'))
当代骨伤科妙方
>>> print unicode_compiled.sub('', u'物理化学名校考研真题详解 (理工科考研辅导系列(化学生物类))')
物理化学名校考研真题详解 

在您的模式中使用UTF-8时,代码点包含单独的字节

>>> '【'
'\xe3\x80\x90'

表示您的字符类匹配任何这些字节; \xe3,或\x80\x90 该字符类中的每个有效字节。

答案 1 :(得分:0)

首先解码你的字符串,你可以摆脱那个 (\ ufffd)字符。

In [1]: import re
   ...: subject = '物理化学名校考研真题详解 (理工科考研辅导系列(化学生物类))'.decode('utf-8')
   ...: reobj = re.compile(r"[\((\[{【]+(\w+|\s+|\S+|\W+)?[)\)\]}】]+", re.IGNORECASE | re.MULTILINE)
   ...: result = reobj.sub("", subject)
   ...: print result
   ...: 
物理化学名校考研真题详解