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

gri*_*ley 127 python numbers

我们如何从Python中删除字符串中的所有非数字字符?

Ned*_*der 241

>>> import re
>>> re.sub("[^0-9]", "", "sdkjh987978asd098as0980a98sd")
'987978098098098'
Run Code Online (Sandbox Code Playgroud)

  • 这可能是re.sub(r"\ D","","sdkjh987978asd098as0980a98sd") (83认同)
  • 那可能是: from re import sub (3认同)

Mar*_*off 79

不确定这是否是最有效的方式,但是:

>>> ''.join(c for c in "abc123def456" if c.isdigit())
'123456'
Run Code Online (Sandbox Code Playgroud)

''.join部分意味着将所有结果字符组合在一起,两者之间没有任何字符.然后剩下的就是列表理解,其中(你可能猜到)我们只采用符合条件的字符串部分isdigit.

  • 对于这个简单的功能,我喜欢这种方法不需要拉入. (10认同)
  • 删除所有非数字==仅保留数字. (7认同)

tzo*_*zot 15

这适用于字符串和unicode对象:

# 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))
Run Code Online (Sandbox Code Playgroud)


ken*_*yut 13

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

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

import re
re.sub("[^\d\.]", "", "$1,999,888.77")
'1999888.77'
Run Code Online (Sandbox Code Playgroud)


Alb*_*rra 9

许多正确的答案,但如果您希望它直接在浮动中,而不使用正则表达式:

x= '$123.45M'

float(''.join(c for c in x if (c.isdigit() or c =='.'))
Run Code Online (Sandbox Code Playgroud)

123.45

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

如果您知道您的号码是整数,请对此进行更改

x='$1123'    
int(''.join(c for c in x if c.isdigit())
Run Code Online (Sandbox Code Playgroud)

1123


Tim*_*ara 6

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

>>> from string import digits
>>> ''.join(c for c in "abc123def456" if c in digits)
'123456'
Run Code Online (Sandbox Code Playgroud)

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

  • 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'
Run Code Online (Sandbox Code Playgroud)


Ale*_*lli 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'
Run Code Online (Sandbox Code Playgroud)

这个translate方法在Unicode字符串上比在字节字符串上使用的方法更简单,也许简单易用,顺便说一句:

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

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

>>> 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'
>>> 
Run Code Online (Sandbox Code Playgroud)

  • (1) 不要硬编码幻数;s/65536/sys.maxunicode/ (2) dict 无条件“过大”,因为输入“可能”包含`(sys.maxunicode - number_of_non_numeric_chars)` 条目。(3) 考虑 string.digits 是否可能不够导致需要破解 unicodedata 模块 (4) 考虑 re.sub(r'(?u)\D+', u'', text) 为简单和潜力速度。 (2认同)