我得到了一个字符串,我想在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")
为什么会发生这种情况,我该如何解决?你知道吗
你有两个问题。你知道吗
首先,原始字符串文字的全部要点是,它们不会将反斜杠转义视为反斜杠转义。所以,
ur"[\u2122\u00ae]"
是字面上的字符[
,\
,u
,2
,1
,等等在python3中,这很好,因为
re
模块将\u
转义理解为Unicode字符,因此模式最终成为包含U+2122
和U+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字符。同样,您可以在源代码中使用它们,但以交互方式,您必须:
我不确定
"a™b®c".decode('cp1252')
是否真的比\u
escapes好,但它会起作用。你知道吗只需删除字符串前面的
r
,它就可以工作了:相关问题 更多 >
编程相关推荐