【问题标题】:Weird behavior of re.sub with utf-8 strings带有 utf-8 字符串的 re.sub 的奇怪行为
【发布时间】:2012-05-07 15:54:15
【问题描述】:

谁能解释一下这种奇怪的行为?我希望这两种替换方法都可以同时工作或不工作。是我一个人还是有人觉得这不连贯?

>>> 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","") 会引发错误!)

【问题讨论】:

  • unicode.replacere.sub 方法不同。
  • 当然。我的观点是,对于相同的输入,它们的行为应该一致。
  • 正是这些问题导致 Python 3 中 Unicode 与字节字符串的执行更加严格。

标签: python regex encoding


【解决方案1】:

来自Unicode Doc

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

来自Re Doc

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

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

【讨论】:

  • 嗯。不太相信国旗的事情; >>> re.sub(u'è','\xe0','',flags=re.UNICODE) 仍然给我回''
  • re 模块完全有可能捕捉到该异常并且对此不透明,只是一种预感,尚未确认。
  • 对我没用 :( 支持 unicode 的 Python 实在是太糟糕了。我已经浪费了 3 天了,仍然无法完成一个超级简单的读取-更改-写入功能。
【解决方案2】:

Python 2.X 对编码的处理有些不自然,需要进行隐式转换。当用户不负责转换时,它将尝试使用 unicode 和非 unicode 字符串。最后,这并不能解决问题:开发人员必须从一开始就确认编码。 Python 2 只是让事情变得不那么明确和不那么明显。

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

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

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

希望有帮助!

【讨论】:

    猜你喜欢
    • 2011-04-14
    • 2019-12-29
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-08
    • 2011-04-08
    相关资源
    最近更新 更多