使用正则表达式在特定单词之前提取数字

时间:2020-11-12 09:17:38

标签: python pandas re

目标

在单词hourshourdaydays之前提取数字

  1. 如何使用|来匹配单词?
s = '2 Approximately 5.1 hours 100 ays 1 s'
re.findall(r"([\d.+-/]+)\s*[days|hours]", s) # note I do not know whether string s contains hours or days

返回

['5.1', '100', '1']

由于100和1不在确切的字小时前,因此它们不应出现。预期

5.1
  1. 如何从匹配结果中提取第一个数字
s1 = '2 Approximately 10.2 +/- 30hours'
re.findall(r"([\d. +-/]+)\s*hours|\s*hours", s)

返回

['10.2 +/- 30']

期望

10.2

请注意,特殊字符+/-.是可选的。当出现.之类的1.3时,将需要在.中显示1.3。但是当1 +/- 0.5发生时,将需要提取1,并且+/-都不应该提取。

我知道我可能会进行拆分,然后取第一个数字

str(re.findall(r"([\d. +-/]+)\s*hours", s1)[0]).split(" ")[1]

给予

'10.2'

但是某些结果仅返回一个数字,因此拆分会导致错误。我应该再做一步还是要一步完成?

请注意,这些字符串s1s2是数据框中的值。因此,将需要使用applylambda之类的函数进行迭代。

2 个答案:

答案 0 :(得分:2)

事实上,我会在这里使用re.findall

units = ["hours", "hour", "days", "day"]   # the order matters here: put plurals first
regex = r'(?:' + '|'.join(units) + r')'
s = '2 Approximately 5.1 hours 100 ays 1 s'
values = re.findall(r'\b(\d+(?:\.\d+)?)\s+' + regex, s)
print(values)  # prints [('5.1')]

如果您想捕获正在使用的单位,则使单位交替捕获,即使用:

regex = r'(' + '|'.join(units) + r')'

那么输出将是:

[('5.1', 'hours')]

答案 1 :(得分:1)

代码

import re
units = '|'.join(["hours", "hour", "hrs", "days", "day", "minutes", "minute", "min"])  # possible units
number = '\d+[.,]?\d*'                              # pattern for number
plus_minus = '\+\/\-'                               # plus minus

cases = fr'({number})(?:[\s\d\-\+\/]*)(?:{units})'

pattern = re.compile(cases)  

测试

print(pattern.findall('2 Approximately 5.1 hours 100 ays 1 s'))   
# Output: [5.1]

print(pattern.findall('2 Approximately 10.2 +/- 30hours'))        
# Output: ['10.2']

print(pattern.findall('The mean half-life for Cetuximab is 114 hours (range 75-188 hours).'))        
# Output: ['114', '75']

print(pattern.findall('102 +/- 30 hours in individuals with rheumatoid arthritis and 68 hours in healthy adults.'))        
# Output: ['102', '68']

print(pattern.findall("102 +/- 30 hrs"))                          
# Output: ['102']

print(pattern.findall("102-130 hrs"))                             
# Output: ['102']

print(pattern.findall("102hrs"))                                  
# Output: ['102']

print(pattern.findall("102 hours"))                               
# Output: ['102']

说明

上面使用了方便的方式,可以将原始字符串(r'...')和字符串插值f'...'组合为:

fr'...'

每个PEP 498

案例字符串:

fr'({number})(?:[\s\d\-\+\/]*)(?:{units})'

零件是顺序:

  • fr'({number})'-捕获组'(\ d + [。,]?\ d *)'用于整数或浮点数
  • r'(?:[\ s \ d-+ /] *)'-非捕获组,用于数字和单位(即空格,+,-,数字,/)之间的允许字符
  • fr'(?:{units})'-单位的非捕获组
相关问题