在Python中删除string中的所有非数字字符

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

>>> import re >>> re.sub("[^0-9]", "", "sdkjh987978asd098as0980a98sd") '987978098098098' 

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

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

''.join部分意味着将所有结果字符组合在一起,而不需要任何字符。 然后剩下的就是一个列表理解,在这里(正如你可能猜到的那样),我们只取得匹配条件isdigit的string部分。

这应该适用于string和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)) 

最快的方法是,如果你需要执行的不仅仅是一个或两个这样的删除操作(或者甚至只是一个,而是一个非常长的string!),就是依赖于string的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方法是不同的,可能简单一点,在Unicodestring上比在字节string上简单一点,btw:

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

你可能想使用映射类而不是实际的字典,尤其是如果你的Unicodestring可能包含非常高的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' >>> 

只是为混合添加另一个选项, 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是原始string的常量的长度。

 >>> digits = frozenset(digits) >>> ''.join(c for c in "abc123def456" if c in digits) '123456' 
 user = (input): print ("hello")