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)