我想提取一个字符串中包含的所有数字。正则表达式和isdigit()方法哪个更适合这个目的?

例子:

line = "hello 12 hi 89"

结果:

[12, 89]

当前回答

这有点晚了,但是您也可以扩展正则表达式来考虑科学符号。

import re

# Format is [(<string>, <expected output>), ...]
ss = [("apple-12.34 ba33na fanc-14.23e-2yapple+45e5+67.56E+3",
       ['-12.34', '33', '-14.23e-2', '+45e5', '+67.56E+3']),
      ('hello X42 I\'m a Y-32.35 string Z30',
       ['42', '-32.35', '30']),
      ('he33llo 42 I\'m a 32 string -30', 
       ['33', '42', '32', '-30']),
      ('h3110 23 cat 444.4 rabbit 11 2 dog', 
       ['3110', '23', '444.4', '11', '2']),
      ('hello 12 hi 89', 
       ['12', '89']),
      ('4', 
       ['4']),
      ('I like 74,600 commas not,500', 
       ['74,600', '500']),
      ('I like bad math 1+2=.001', 
       ['1', '+2', '.001'])]

for s, r in ss:
    rr = re.findall("[-+]?[.]?[\d]+(?:,\d\d\d)*[\.]?\d*(?:[eE][-+]?\d+)?", s)
    if rr == r:
        print('GOOD')
    else:
        print('WRONG', rr, 'should be', r)

给予一切美好!

此外,您还可以查看AWS Glue内置正则表达式

其他回答

我将使用regexp:

>>> import re
>>> re.findall(r'\d+', "hello 42 I'm a 32 string 30")
['42', '32', '30']

这也匹配bla42bla中的42。如果你只想用单词边界(空格,句号,逗号)分隔数字,你可以使用\b:

>>> re.findall(r'\b\d+\b', "he33llo 42 I'm a 32 string 30")
['42', '32', '30']

以数字列表而不是字符串列表结束:

>>> [int(s) for s in re.findall(r'\b\d+\b', "he33llo 42 I'm a 32 string 30")]
[42, 32, 30]

注意:这对负整数不起作用

如果你知道字符串中只有一个数字,比如'hello 12 hi',你可以尝试filter。

例如:

In [1]: int(''.join(filter(str.isdigit, '200 grams')))
Out[1]: 200
In [2]: int(''.join(filter(str.isdigit, 'Counters: 55')))
Out[2]: 55
In [3]: int(''.join(filter(str.isdigit, 'more than 23 times')))
Out[3]: 23

但是要小心!!:

In [4]: int(''.join(filter(str.isdigit, '200 grams 5')))
Out[4]: 2005
line2 = "hello 12 hi 89"  # this is the given string 
temp1 = re.findall(r'\d+', line2) # find number of digits through regular expression
res2 = list(map(int, temp1))
print(res2)

可以使用findall表达式通过digit搜索字符串中的所有整数。

在第二步中,创建一个列表res2,并将string中找到的数字添加到该列表中。

我很惊讶地发现还没有人提到itertools的用法。Groupby作为实现这一目标的替代方案。

你可以使用itertools.groupby()和str.isdigit()来从字符串中提取数字,如下:

from itertools import groupby
my_str = "hello 12 hi 89"

l = [int(''.join(i)) for is_digit, i in groupby(my_str, str.isdigit) if is_digit]

由l保持的值将是:

[12, 89]

PS:这只是为了说明,作为一种替代方案,我们也可以使用groupby来实现这一点。但这不是一个推荐的解决方案。如果您想实现这一点,您应该使用基于使用str.isdigit作为过滤器的列表理解的fmark的接受答案。

这有点晚了,但是您也可以扩展正则表达式来考虑科学符号。

import re

# Format is [(<string>, <expected output>), ...]
ss = [("apple-12.34 ba33na fanc-14.23e-2yapple+45e5+67.56E+3",
       ['-12.34', '33', '-14.23e-2', '+45e5', '+67.56E+3']),
      ('hello X42 I\'m a Y-32.35 string Z30',
       ['42', '-32.35', '30']),
      ('he33llo 42 I\'m a 32 string -30', 
       ['33', '42', '32', '-30']),
      ('h3110 23 cat 444.4 rabbit 11 2 dog', 
       ['3110', '23', '444.4', '11', '2']),
      ('hello 12 hi 89', 
       ['12', '89']),
      ('4', 
       ['4']),
      ('I like 74,600 commas not,500', 
       ['74,600', '500']),
      ('I like bad math 1+2=.001', 
       ['1', '+2', '.001'])]

for s, r in ss:
    rr = re.findall("[-+]?[.]?[\d]+(?:,\d\d\d)*[\.]?\d*(?:[eE][-+]?\d+)?", s)
    if rr == r:
        print('GOOD')
    else:
        print('WRONG', rr, 'should be', r)

给予一切美好!

此外,您还可以查看AWS Glue内置正则表达式