Python:从字符串中删除除数字之外的字符

时间:2009-09-20 12:14:18

标签: python string

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

17 个答案:

答案 0 :(得分:160)

使用re.sub,如下所示:

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

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

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

>>> filter(lambda x: x.isdigit(), "aas30dsa20")
'3020'

因为在Python 3k中,filter返回迭代器而不是list,所以您可以使用以下代码:

>>> ''.join(filter(lambda x: x.isdigit(), "aas30dsa20"))
'3020'

答案 1 :(得分:104)

在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

...显示性能优势消失,对于这种“删除”任务,并且性能下降。

答案 2 :(得分:57)

s=''.join(i for i in s if i.isdigit())

另一种发电机变种。

答案 3 :(得分:16)

您可以使用过滤器:

filter(lambda x: x.isdigit(), "dasdasd2313dsa")

在python3.0上你必须加入这个(有点难看:()

''.join(filter(lambda x: x.isdigit(), "dasdasd2313dsa"))

答案 4 :(得分:11)

沿着拜耳的回答:

''.join(i for i in s if i.isdigit())

答案 5 :(得分:10)

您可以使用Regex

轻松完成
>>> import re
>>> re.sub("\D","","£70,000")
70000

答案 6 :(得分:7)

x.translate(None, string.digits)

将删除字符串中的所有数字。要删除字母并保留数字,请执行以下操作:

x.translate(None, string.letters)

答案 7 :(得分:5)

评论中提到他想保留小数位。这可以通过re.sub方法(根据第二个和恕我直言最佳答案)通过明确列出要保留的字符来完成。

>>> re.sub("[^0123456789\.]","","poo123.4and5fish")
'123.45'

答案 8 :(得分:4)

Python 3的快速版本:

# xx3.py
from collections import defaultdict
import string
_NoneType = type(None)

def keeper(keep):
    table = defaultdict(_NoneType)
    table.update({ord(c): c for c in keep})
    return table

digit_keeper = keeper(string.digits)

这是性能比较与正则表达式:

$ python3.3 -mtimeit -s'import xx3; x="aaa12333bb445bb54b5b52"' 'x.translate(xx3.digit_keeper)'
1000000 loops, best of 3: 1.02 usec per loop
$ python3.3 -mtimeit -s'import re; r = re.compile(r"\D"); x="aaa12333bb445bb54b5b52"' 'r.sub("", x)'
100000 loops, best of 3: 3.43 usec per loop

对我而言,它比正则表达式快3倍多。它也比class Del更快,因为defaultdict在C中执行所有查找,而不是(慢)Python。这是我在同一系统上的那个版本,用于比较。

$ python3.3 -mtimeit -s'import xx; x="aaa12333bb445bb54b5b52"' 'x.translate(xx.DD)'
100000 loops, best of 3: 13.6 usec per loop

答案 9 :(得分:2)

丑陋但有效:

>>> s
'aaa12333bb445bb54b5b52'
>>> a = ''.join(filter(lambda x : x.isdigit(), s))
>>> a
'1233344554552'
>>>

答案 10 :(得分:1)

使用生成器表达式:

>>> s = "foo200bar"
>>> new_s = "".join(i for i in s if i in "0123456789")

答案 11 :(得分:1)

$ python -mtimeit -s'import re;  x="aaa12333bb445bb54b5b52"' 're.sub(r"\D", "", x)'
  

100000次循环,每循环3:2.48最佳。

$ python -mtimeit -s'import re; x="aaa12333bab445bb54b5b52"' '"".join(re.findall("[a-z]+",x))'
  

100000次循环,每循环最好3:2.02 usc

$ python -mtimeit -s'import re;  x="aaa12333bb445bb54b5b52"' 're.sub(r"\D", "", x)'
  

100000次循环,每循环最好3:2.37

$ python -mtimeit -s'import re; x="aaa12333bab445bb54b5b52"' '"".join(re.findall("[a-z]+",x))'
  

100000次循环,每个循环中最好为3:1.97 usc

我观察到联接比sub快。

答案 12 :(得分:0)

不是一个班轮而是非常简单:

var i:Int=0
var JoinedStream:DStream[ConsumerRecord[String,String]]=null;

var firstStream = KafkaUtils.createDirectStream[String, String](streamingContext, LocationStrategies.PreferConsistent, ConsumerStrategies.Subscribe[String, String](Array(topicNameONe(0).asInstanceOf[JsString].value), kafkaParams))

for(i <- 0 to topicNameONe.length-1 )
  {
    JoinedStream=firstStream.union(KafkaUtils.createDirectStream[String, String](streamingContext, LocationStrategies.PreferConsistent, ConsumerStrategies.Subscribe[String, String](Array(topicNameONe(i).asInstanceOf[JsString].value), kafkaParams)))
  }`

答案 13 :(得分:0)

您可以阅读每个字符。如果是数字,则将其包括在答案中。 str.isdigit() method是一种判断字符是否为数字的方法。

your_input = '12kjkh2nnk34l34'
your_output = ''.join(c for c in your_input if c.isdigit())
print(your_output) # '1223434'

答案 14 :(得分:0)

我用了这个。 'letters'应包含所有要删除的字母:

Output = Input.translate({ord(i): None for i in 'letters'}))

示例:

Input = "I would like 20 dollars for that suit" Output = Input.translate({ord(i): None for i in 'abcdefghijklmnopqrstuvwxzy'})) print(Output)

输出: 20

答案 15 :(得分:0)

my_string="sdfsdfsdfsfsdf353dsg345435sdfs525436654.dgg(" 
my_string=''.join((ch if ch in '0123456789' else '') for ch in my_string)
print(output:+my_string)

输出:353345435525436654

答案 16 :(得分:0)

import re

string = '1abcd2XYZ3'
string_without_letters = re.sub(r'[a-z]', '', string.lower())

result ='123'