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

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

282913 次浏览

使用 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'

使用生成器表达式:

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

丑陋但有效:

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

类似于拜耳的回答:

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

你可以使用 filter:

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

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

''.join(filter(lambda x: x.isdigit(), "dasdasd2313dsa"))
s=''.join(i for i in s if i.isdigit())

另一个发电机变种。

在 Python2.* 中,迄今为止最快的方法是 .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方法是非常值得了解和使用的。另一种流行的非回归方法... ... :

$ 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% ,所以 abc0的方法比 RE 快了一个数量级。

在 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

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

行动在评论中提到,他想保留小数点后的位置。这可以通过 re.sub 方法(根据第二个和 IMHO 最佳答案)通过显式列出要保留的字符来完成。

>>> re.sub("[^0123456789\.]","","poo123.4and5fish")
'123.45'
x.translate(None, string.digits)

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

x.translate(None, string.letters)

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

您可以很容易地使用正则表达式进行此操作

>>> import re
>>> re.sub("\D","","£70,000")
70000

不是一句话,而是非常简单:

buffer = ""
some_str = "aas30dsa20"


for char in some_str:
if not char.isdigit():
buffer += char


print( buffer )
$ 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每个循环使用

$ 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的最佳值

我已经观察到,连接比子连接更快。

你可以读每个字符。如果是数字,则将其包含在答案中。str.isdigit() 方法是一种知道字符是否为数字的方法。

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

我用了这个。 'letters'应该包含所有你想去掉的字母:

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

例如:

输入 = “我想要20美元买那套衣服” Output = Input.trans ({ ord (i) : 在‘ abcdefghiklmnopqrstuvwxzy’}中 i 没有) 打印(输出)

产出: 20

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

产出: 353345435525436654

试试:

import re


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

这应该给予:

123

你可以使用 join + filter + lambda:

''.join(filter(lambda s: s.isdigit(), "20 years ago, 2 months ago, 2 days ago"))

产出: ‘2022’

还有一个:

import re


re.sub('[^0-9]', '', 'ABC123 456')

结果:

'123456'