使用 Python 从字符串中删除数字以外的字符?

新手上路,请多包涵

如何从字符串中删除除数字以外的所有字符?

原文由 Jan Tojnar 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 414
2 个回答

在 Python 2.* 中,目前最快的方法是 .translate 方法:

 >>> x='aaa12333bb445bb54b5b52'
>>> import string
>>> all=string.maketrans('','')
>>> nodigs=all.translate(all, string.digits)
>>> x.translate(all, nodigs)
'1233344554552'
>>>

string.maketrans 制作一个翻译表(长度为 256 的字符串),在这种情况下与 ''.join(chr(x) for x in range(256)) 相同(制作速度更快;-)。 .translate 应用翻译表(这里是无关紧要的,因为 all 本质上意味着身份)并删除第二个参数中存在的字符 - 关键部分。

.translate 在 Unicode 字符串(和 Python 3 中的字符串)上的工作方式非常不同—— 希望问题能具体说明对哪个 Python 主要版本感兴趣!)——不是这么简单,也不是这么快,虽然还是蛮好用的。

回到 2.*,性能差异令人印象深刻……:

 $ python -mtimeit -s'import string; all=string.maketrans("", ""); nodig=all.translate(all, string.digits); x="aaa12333bb445bb54b5b52"' 'x.translate(all, nodig)'
1000000 loops, best of 3: 1.04 usec per loop
$ python -mtimeit -s'import re;  x="aaa12333bb445bb54b5b52"' 're.sub(r"\D", "", x)'
100000 loops, best of 3: 7.9 usec per loop

将速度提高 7-8 倍并不是花生,因此 translate 方法非常值得了解和使用。另一种流行的非 RE 方法……:

 $ python -mtimeit -s'x="aaa12333bb445bb54b5b52"' '"".join(i for i in x if i.isdigit())'
100000 loops, best of 3: 11.5 usec per loop

比 RE 慢 50%,所以 .translate 方法比它高一个数量级。

在 Python 3 或 Unicode 中,您需要传递 .translate 一个映射(使用序数,而不是直接使用字符,作为键)返回 None 用于您要删除的内容。这里有一个方便的方式来表达删除“除了”几个字符之外的所有内容:

 import string

class Del:
  def __init__(self, keep=string.digits):
    self.comp = dict((ord(c),c) for c in keep)
  def __getitem__(self, k):
    return self.comp.get(k)

DD = Del()

x='aaa12333bb445bb54b5b52'
x.translate(DD)

还发出 '1233344554552' 。然而,把它放在 xx.py 中我们有……:

 $ python3.1 -mtimeit -s'import re;  x="aaa12333bb445bb54b5b52"' 're.sub(r"\D", "", x)'
100000 loops, best of 3: 8.43 usec per loop
$ python3.1 -mtimeit -s'import xx; x="aaa12333bb445bb54b5b52"' 'x.translate(xx.DD)'
10000 loops, best of 3: 24.3 usec per loop

…这表明性能优势消失了,对于这种“删除”任务,并成为性能下降。

原文由 Alex Martelli 发布,翻译遵循 CC BY-SA 3.0 许可协议

使用 re.sub ,像这样:

 >>> import re
>>> re.sub('\D', '', 'aas30dsa20')
'3020'

\D 匹配任何非数字字符,因此上面的代码实质上是将每个非数字字符替换为空字符串。

或者您可以使用 filter ,就像这样(在 Python 2 中):

 >>> filter(str.isdigit, 'aas30dsa20')
'3020'

由于在 Python 3 中, filter 返回一个迭代器而不是 list ,您可以使用以下代替:

 >>> ''.join(filter(str.isdigit, 'aas30dsa20'))
'3020'

原文由 João Silva 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题