【问题标题】:Leave only alphanumeric symbols in string in Python?在 Python 中的字符串中只保留字母数字符号?
【发布时间】:2016-07-07 13:47:02
【问题描述】:

我正在使用 Python 2.7。在 SO 上,我发现了以下用于删除非单词字符的正则表达式:

pat = re.compile('[\W]+', re.UNICODE)

我写了下一个函数:

def leave_only_alphanumeric(string):
  pat = re.compile('[\W]+', re.UNICODE)
  return re.sub(pat,' ',string)

尽管在以下字符串上:

kr\xc3\xa9m

它会产生错误的结果:

kr\xc3 m 

\xa9 已从字符串中删除,但不应删除。

【问题讨论】:

  • 你是如何创建字符串的?具体来说,如果它在您的代码中,您是否在字符串前面加上 u
  • 您的文本是在unicode 对象还是str 对象中?
  • @Bakuriu leave_only_alphanumeric(u'kr\xc3\xa9m')
  • 这就是问题所在。它应该是u"kr\xe9m""kr\xc3\xa9m"。否则,您的字符串中包含字符 é,而不是您所期望的 é。因此,您的代码删除了 ©,但没有删除 Ã.
  • 如果您正在编写 unicode 文本,您应该:1) 确保您的编辑器使用 utf-8 2) 在文件顶部添加 # -.- coding: utf-8 -.- 3) 使用 leave_only_alphanumeric(u'krém')。或者,使用带有 unicode 转义 的 unicode 文字:u'kr\u00e9m'。否则,您正在编写 bytes 所以没有 u 前缀并使用两字节转义,然后您必须将 decode 它转换为 unicode 对象。但是,您不能混合使用这两种表示。

标签: python regex unicode python-2.x


【解决方案1】:

您混淆了 unicode 代码点和 utf-8 编码。

您要处理的字母是é,代码点u00e9
它以 utf-8 编码为两个字节,0xc3 和 0xa9。

试试:

>>> "kr\xc3\xa9m".decode('utf-8')
u'kr\xe9m'
>>> print("kr\xc3\xa9m")
krém
>>> print(u"kr\xe9m")
krém

对于u"",您必须使用实际的代码点。在使用原始"" 时,python 只会看到一个字节链。

请注意,第二行仅适用,因为我的终端编码是 utf-8,否则我会看到乱码输出。

结果,你的字符串不是你想的那样:

>>> print(u"kr\xc3\xa9m")
krém

您实际上输入了两个字符,代码点为u00c3u00a9。前者是Ã,它是一个字母字符,第二个是©,这不是,这也是你的代码删除它的原因。

现在正在使用您的代码:

>>> def leave_only_alphanumeric(string):
...   pat = re.compile('[\W]+', re.UNICODE)
...   return re.sub(pat,' ',string)
...
>>> leave_only_alphanumeric(u"kr\xe9m")
u'kr\xe9m'
>>> leave_only_alphanumeric("kr\xc3\xa9m")   # this is not unicode
'kr\xc3 m'                                   #     -> thus the wrong result
>>> leave_only_alphanumeric("kr\xc3\xa9m".decode('utf-8'))
u'kr\xe9m'
>>> leave_only_alphanumeric("kr\xc3\xa9m".decode('utf-8')).encode('utf-8')
'kr\xc3\xa9m'
>>>

【讨论】:

    【解决方案2】:

    我相信正则表达式在这里可能有点矫枉过正。

    def leave_only_alphanumeric(string):
        return ''.join(ch if ch.isalnum() else ' ' for ch in string)
    

    编辑:您的标题显示“字母数字”,但您的代码也删除了数字。所以有点不清楚。

    【讨论】:

    • 它不做同样的事情。
    • @spectras 确实如此,但现在确实如此.. :)
    猜你喜欢
    • 2016-03-16
    • 1970-01-01
    • 1970-01-01
    • 2012-04-09
    • 2019-05-26
    • 2023-03-16
    • 2013-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多