如何在Python中从字符串中提取数字?

699
我想从一个字符串中提取所有数字。对于此目的,正则表达式和isdigit()方法哪个更适合?
示例:
line = "hello 12 hi 89"

结果:

[12, 89]

4
很遗憾,示例输入数据过于简单,导致只产生了一些朴素的解法。常规情况下,输入字符串应包含数字相邻的更有趣的字符。一个稍微具有挑战性的示例输入: '''gimme digits from "12", 34, '56', -789.''' 抱歉,样本输入数据太过简单,这会引发一些朴素的解决方案。通常,常见情况下的输入字符串应该包含比数字相邻更有趣的字符。以下是一个稍微有些具有挑战的输入示例:'''gimme digits from "12", 34, '56', -789.''' - MarkHu
20个回答

13
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表达式,您可以通过数字搜索字符串中的所有整数。

在第二步中创建一个名为res2的列表,并将字符串中找到的数字添加到此列表中。


2
提供的答案因为质量低被标记为待审核。以下是如何编写一个好的回答?的一些指南。该提供的答案可能是正确的,但需要有进一步的解释。只有代码的答案并不被认为是“好”的答案。来自于审核 - Trenton McKinney

10

我添加这个答案是因为没有人使用异常处理方式并且因为这种方法也适用于浮点数。

a = []
line = "abcd 1234 efgh 56.78 ij"
for word in line.split():
    try:
        a.append(float(word))
    except ValueError:
        pass
print(a)

输出:
[1234.0, 56.78]

7
这个答案还包括字符串中数字为浮点数的情况。
def get_first_nbr_from_str(input_str):
    '''
    :param input_str: strings that contains digit and words
    :return: the number extracted from the input_str
    demo:
    'ab324.23.123xyz': 324.23
    '.5abc44': 0.5
    '''
    if not input_str and not isinstance(input_str, str):
        return 0
    out_number = ''
    for ele in input_str:
        if (ele == '.' and '.' not in out_number) or ele.isdigit():
            out_number += ele
        elif out_number:
            break
    return float(out_number)

5
我很惊讶地发现还没有人提到使用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]
< p > l 所持有的值将是:

[12, 89]

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


3
我找到的最干净的方法:
>>> data = 'hs122 125 &55,58, 25'
>>> new_data = ''.join((ch if ch in '0123456789.-e' else ' ') for ch in data)
>>> numbers = [i for i in new_data.split()]
>>> print(numbers)
['122', '125', '55', '58', '25']

或者是这样:
>>> import re
>>> data = 'hs122 125 &55,58, 25'
>>> numbers = re.findall(r'\d+', data)
>>> print(numbers)
['122', '125', '55', '58', '25']

两种提出的解决方案都不是同质的。这个正则表达式的解决方案是:re.findall(r'[\d.e-]+', data) - lalebarde

2

由于这些方法都没有涉及到我需要查找的实际财务数据,如Excel和Word文档,因此这里是我的变化。它处理整数、浮点数、负数、货币数字(因为它不依赖于分割),并且可以选择舍弃小数部分只返回整数,或者返回所有内容。

它还处理了印度缅甸数字系统,其中逗号不规则地出现,而不是每三个数字一组。

它不能处理科学计数法或括号内放置负数的预算——它们将显示为正数。

它也不提取日期。有更好的方法来在字符串中查找日期。

import re
def find_numbers(string, ints=True):            
    numexp = re.compile(r'[-]?\d[\d,]*[\.]?[\d{2}]*') #optional - in front
    numbers = numexp.findall(string)    
    numbers = [x.replace(',','') for x in numbers]
    if ints is True:
        return [int(x.replace(',','').split('.')[0]) for x in numbers]            
    else:
        return numbers

2

@jmnas,我喜欢你的回答,但它没有找到浮点数。我正在编写一个脚本来解析发送到CNC铣床的代码,并需要找到可以是整数或浮点数的X和Y维度,因此我将你的代码改为以下内容。这可以找到具有正值和负值的int、float。仍然无法找到十六进制格式的值,但您可以在num_char元组中添加“x”和“A”到“F”,我认为它会解析像“0x23AC”这样的东西。

s = 'hello X42 I\'m a Y-32.35 string Z30'
xy = ("X", "Y")
num_char = (".", "+", "-")

l = []

tokens = s.split()
for token in tokens:

    if token.startswith(xy):
        num = ""
        for char in token:
            # print(char)
            if char.isdigit() or (char in num_char):
                num = num + char

        try:
            l.append(float(num))
        except ValueError:
            pass

print(l)

2
str1 = "There are 2 apples for 4 persons"

# printing original string 
print("The original string : " + str1) # The original string : There are 2 apples for 4 persons

# using List comprehension + isdigit() +split()
# getting numbers from string 
res = [int(i) for i in str1.split() if i.isdigit()]

print("The numbers list is : " + str(res)) # The numbers list is : [2, 4]

0
我找到的最佳方案如下。它可以提取数字并消除任何类型的字符。
def extract_nbr(input_str):
    if input_str is None or input_str == '':
        return 0

    out_number = ''
    for ele in input_str:
        if ele.isdigit():
            out_number += ele
    return float(out_number)    

最好使用join函数来连接列表,而不是使用+=操作符来连接字符串。 - OneCricketeer

0
正则表达式
regx_pattern= r'\d+\.\d+|\d+'

Python 实现:

import re

regx_pattern = r'\d+\.\d+|\d+'
txt = "The price is $12.99 and the quantity is 5 21321 dasdsa 123213."
matches = re.findall(regx_pattern, txt)
print(matches)

输出:

['12.99', '5', '21321', '123213']

一点解释:

它将匹配数字'\d+' 或者 匹配带有小数点的数字。 Python实现会找到所有匹配并将它们放入一个列表中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接