re.sub使用utf-8字符串的奇怪行为

时间:2012-05-07 15:54:16

标签: python regex encoding

有人能解释我这种奇怪的行为吗?我希望两种替换方法可以同时工作或不工作。是仅仅是我还是有人没有发现这一点是连贯的?

>>> u'è'.replace("\xe0","")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe0 in position 0: ordinal not in range(128)
>>> re.sub(u'è','\xe0','',flags=re.UNICODE)
''

(请注意,我不是要求解释为什么u'è'.replace(“\ xe0”,“”)引发错误!)

2 个答案:

答案 0 :(得分:2)

来自Unicode Doc

  

这些方法的参数可以是Unicode字符串或8位   字符串。在携带之前,8位字符串将转换为Unicode   出局;将使用Python的默认ASCII编码   大于127的字符将导致异常

来自Re Doc

  

该模块提供类似于的正则表达式匹配操作   在Perl中找到的那些。要搜索的模式和字符串都可以   Unicode字符串以及8位字符串。

由于Re模块没有明确指定Unicode标志,因此它不会尝试转换,因此不会引发错误。这就是他们没有连贯行为的原因

答案 1 :(得分:0)

Python 2.X对编码有一些不自然的处理,它采用隐式转换。当转换未由用户处理时,它将尝试使用unicode和no-unicode字符串。最后,这并没有解决问题:开发人员必须从一开始就确认编码。 Python 2只是使事情变得不那么明确,而且不那么明显。

>>> u'è'.replace(u"\xe0", u"")
u'\xe8'

这是你原来的例子,除了我特意告诉Python所有字符串都是unicode。如果你不这样做,Python会尝试转换它们。并且因为Python 2中的默认编码是ASCII,显然会因为你的例子而失败。

编码是一个棘手的主题,但有一些好的习惯(比如早期转换,总是确定程序在给定点处理什么类型的数据),它通常(我坚持,通常)顺利进行。

希望有所帮助!