为什么python2的re模块不能识别u'®'ch

2024-09-28 05:17:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我得到了一个字符串,我想在Python2中re.sub这个字符串,所以我尝试了下面的语句,它成功了

>>> import re
>>> re.sub(u"[™®]", "", u"a™b®c")
'abc'

但是当我尝试下面的语句时,它在两个Windows 10(Python 2.7.15 | Anaconda,Inc.|(默认值,2018年5月1日,18:37:09)[MSC v.1500 64位(AMD64)]和win32上都失败了。你知道吗

>>> re.sub(ur"[\u2122\u00ae]", "", u"a™b®c")
u'a?b?c'

我尝试了Python and regular expression with Unicode的解决方案,但也没有成功。你知道吗

>>> myre = re.compile(ur'[\u2122\u00ae]', re.UNICODE)
>>> print myre.sub('', u"a™b®c")

为什么会发生这种情况,我该如何解决?你知道吗


Tags: 字符串importrewindowsanaconda语句amd64inc
2条回答

你有两个问题。你知道吗


首先,原始字符串文字的全部要点是,它们不会将反斜杠转义视为反斜杠转义。所以,ur"[\u2122\u00ae]"是字面上的字符[\u21,等等

在python3中,这很好,因为re模块将\u转义理解为Unicode字符,因此模式最终成为包含U+2122U+00AE的character类,完全如您所愿。但是在Python2中,它没有,所以character类最终是一堆无用的垃圾。你知道吗

如果您将其更改为使用非原始字符串文字,则可以解决该问题:u"[\u2122\u00ae]"。当然,这会带来所有其他潜在的问题,使人们希望在正则表达式中首先使用原始字符串文字,但幸运的是,这里没有这些文字。你知道吗


第二个问题是,在Unicode文本中使用Unicode字符时没有编码声明。同样,在Python3中不是问题,但在Python2中是问题。你知道吗

当您键入"a™b®c"时,很有可能您实际上给Python的不是\u2122字符,而是\u0099字符。您的控制台可能是cp1252之类的,所以当您键入或粘贴时,它实际上为Python提供的是U+0099,而不是U+2122。当然,您的控制台也会错误地显示内容,因此U+0099最终看起来像。但是Python根本不知道发生了什么。它只是看到U+0099和U+2122不是同一个字符,因此没有匹配。(您的第一个示例之所以有效,是因为您的搜索字符串具有不正确的\u0099,所以它恰好匹配。)

在源代码中,您可以通过添加编码声明来告诉Python您正在使用cp1252,或者首先告诉编辑器使用UTF-8而不是cp1252来解决这个问题。但是在交互式解释器中,您可以得到您的控制台想要的任何编码,并且没有地方放置编码声明。你知道吗

真的,没什么好办法。你知道吗

嗯,有:升级到python3。它存在的主要原因首先是为了让像这样的Unicode头痛消失,而Python2离生命结束还有不到一年半的时间,那么您真的想学习如何在Python2中处理Unicode头痛吗?你知道吗

您还可以得到一个UTF-8终端(Python也可以识别它)。在macOS或最新的Linux发行版上,这是自动的;在Windows上,这要困难得多,而且可能不是您想要的方式。你知道吗

所以,唯一的选择就是在交互式解释器上永远不要在Unicode文本中使用Unicode字符。同样,您可以在源代码中使用它们,但以交互方式,您必须:

  • 使用反斜杠转义符。你知道吗
  • 使用非Unicode文本并仔细地对它们进行解码。你知道吗

我不确定"a™b®c".decode('cp1252')是否真的比\uescapes好,但它会起作用。你知道吗

只需删除字符串前面的r,它就可以工作了:

re.sub(u"[\u2122\u00ae]", "", u"a™b®c")

相关问题 更多 >

    热门问题