Python:从string中提取数字

我会提取一个string中包含的所有数字。 哪个更适合于目的,正则expression式或isdigit()方法?

例:

 line = "hello 12 hi 89" 

结果:

 [12, 89] 

如果您只想提取正整数,请尝试以下操作:

 >>> str = "h3110 23 cat 444.4 rabbit 11 2 dog" >>> [int(s) for s in str.split() if s.isdigit()] [23, 11, 2] 

我认为这比正则expression式更好,原因有三。 首先,你不需要另一个模块; 其次,它更可读,因为你不需要parsing正则expression式的迷你语言; 第三,速度更快(因此可能更为pythonic):

 python -m timeit -s "str = 'h3110 23 cat 444.4 rabbit 11 2 dog' * 1000" "[s for s in str.split() if s.isdigit()]" 100 loops, best of 3: 2.84 msec per loop python -m timeit -s "import re" "str = 'h3110 23 cat 444.4 rabbit 11 2 dog' * 1000" "re.findall('\\b\\d+\\b', str)" 100 loops, best of 3: 5.66 msec per loop 

这将不会识别hex格式的浮点数,负整数或整数。 如果你不能接受这些限制, 苗条的回答下面将做的伎俩。

我会使用正则expression式:

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

这也将匹配从bla42bla 42。 如果您只希望以字边界(空格,句点,逗号)分隔的数字,则可以使用\ b:

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

要结束一个数字列表而不是一个string列表:

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

这是不是迟了一点,但你可以扩大正则expression式来说明科学记数法。

 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\'ma Y-32.35 string Z30', ['42', '-32.35', '30']), ('he33llo 42 I\'ma 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) 

给所有好的!

我假设你想漂浮不只是整数,所以我会做这样的事情:

 l = [] for t in s.split(): try: l.append(float(t)) except ValueError: pass 

请注意,这里发布的其他一些解决scheme不适用于负数:

 >>> re.findall(r'\b\d+\b', 'he33llo 42 I\'ma 32 string -30') ['42', '32', '30'] >>> '-3'.isdigit() False 

如果你知道这只是string中的一个数字,例如'你好12你好',你可以尝试filter。

例如:

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

但要小心! :

 In [4]: int(filter(str.isdigit, '200 grams 5')) Out[4]: 2005 

这个答案也包含数字在string中浮动的情况

 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) 

我很惊讶地看到没有人提到itertools.groupby作为替代实现这一点的用法。

您可以使用itertools.groupby()以及str.isdigit()来从string中提取数字,如下所示:

 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] 

由于这些都不涉及我需要find的excel和word文档中的现实世界财务数据,所以这里是我的变化。 它可以处理整数,浮点数,负数,货币数(因为它不会在分割时回复),并且可以select丢弃小数部分并返回整数,或返回所有内容。

它也处理印度叻号系统逗号出现不规则,不是每隔3个数字。

它不处理预算中括号内的科学记数法或负数 – 会显得积极。

它也不提取date。 有更好的方法来查找string中的date。

 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 

@jmnas,我喜欢你的答案,但是没有find花车。 我正在编写一个脚本来parsing代码到CNC磨机的代码,并且需要find可以是整数或浮点数的X和Y维度,所以我将你的代码调整到了下面的代码中。 这发现int,浮动与积极和消极vals。 仍然没有findhex格式的值,但你可以通过“F”添加“x”和“A”到num_char元组,我认为它会parsing的东西,如“0x23AC”。

 s = 'hello X42 I\'ma 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) 

我发现最好的select是在下面。 它会提取数字,并可以消除任何types的字符。

 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)