在Python中从字符串中删除所有非数字字符


Answers:



88

不知道这是否是最有效的方法,但是:

>>> ''.join(c for c in "abc123def456" if c.isdigit())
'123456'

''.join部分意味着将所有结果字符组合在一起,而中间没有任何字符。然后剩下的就是列表推导了,在这里(您可能会猜到),我们只取匹配条件的字符串部分isdigit


1
相反。我认为您的意思是“不是c.isdigit()”
Ryan R. Rosario,2009年

7
删除所有非数字==仅保留数字。
Mark Rushakoff 09年

10
我喜欢这种方法,对于这个简单的功能,不需要重新输入。
triunenature 2015年

请注意,与使用str.translate的实现不同,此解决方案在python 2.7和3.4中均有效。谢谢!
亚历克斯

1
我更喜欢这种选择。对我来说,使用正则表达式似乎有些矫kill过正。
alfredocambera

18

这对于Python2中的字符串和unicode对象均适用,在Python3中的字符串和字节均适用:

# python <3.0
def only_numerics(seq):
    return filter(type(seq).isdigit, seq)

# python ≥3.0
def only_numerics(seq):
    seq_type= type(seq)
    return seq_type().join(filter(seq_type.isdigit, seq))

9

只是为了给混合添加另一个选项,string模块内有几个有用的常量。尽管在其他情况下更有用,但可以在此处使用它们。

>>> from string import digits
>>> ''.join(c for c in "abc123def456" if c in digits)
'123456'

模块中有几个常量,包括:

  • ascii_letters (abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ)
  • hexdigits (0123456789abcdefABCDEF)

如果您大量使用这些常量,那么将它们隐瞒为可能是值得的frozenset。这将启用O(1)查找,而不是O(n),其中n是原始字符串的常数长度。

>>> digits = frozenset(digits)
>>> ''.join(c for c in "abc123def456" if c in digits)
'123456'

” .join(如果c.isdigit()如果c.isdigit(),则在c中为“ abc123def456”中的c)在我的python 3.4中起作用
EinoMäkitalo16

7

@Ned Batchelder和@newacct提供了正确的答案,但是...

万一您的字符串中有逗号(,)小数点(。),以防万一:

import re
re.sub("[^\d\.]", "", "$1,999,888.77")
'1999888.77'

5

如果您需要执行的删除操作不止一个或两个(或什至只执行一个,但是要处理非常长的字符串!-),最快的方法是依靠translate字符串方法,即使它确实需要一些准备:

>>> import string
>>> allchars = ''.join(chr(i) for i in xrange(256))
>>> identity = string.maketrans('', '')
>>> nondigits = allchars.translate(identity, string.digits)
>>> s = 'abc123def456'
>>> s.translate(identity, nondigits)
'123456'

translate方法在Unicode字符串上比在字节字符串btw上有所不同,使用起来可能更简单一些:

>>> unondig = dict.fromkeys(xrange(65536))
>>> for x in string.digits: del unondig[ord(x)]
... 
>>> s = u'abc123def456'
>>> s.translate(unondig)
u'123456'

您可能想使用映射类而不是实际的字典,尤其是如果您的Unicode字符串可能包含具有非常高ord值的字符(这会使字典过大;-)时,尤其如此。例如:

>>> class keeponly(object):
...   def __init__(self, keep): 
...     self.keep = set(ord(c) for c in keep)
...   def __getitem__(self, key):
...     if key in self.keep:
...       return key
...     return None
... 
>>> s.translate(keeponly(string.digits))
u'123456'
>>> 

2
(1)不要硬编码魔术数字;s / 65536 / sys.maxunicode /(2)字典无条件地“过大”,因为输入“可能”包含(sys.maxunicode - number_of_non_numeric_chars)条目。(3)考虑string.digits是否可能不足以导致需要破解unicodedata模块。(4)考虑re.sub(r'(?u)\ D +',u'',text)的简单性和潜力速度。
约翰·马钦

2

很多正确的答案,但是如果您直接使用浮点数,而不使用正则表达式,则可以:

x= '$123.45M'

float(''.join(c for c in x if (c.isdigit() or c =='.'))

123.45

您可以根据需要更改逗号的要点。

如果您知道您的数字是整数,请为此更改

x='$1123'    
int(''.join(c for c in x if c.isdigit())

1123

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.