使用正则表达式提取特定单词前的数字
Use regular expression to extract numbers before specific words
目标
提取单词 hours
、hour
、day
或 days
之前的数字
- 如何使用
|
来匹配单词?
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
return
['5.1', '100', '1']
由于 100 和 1 不在确切的单词小时之前,因此它们不应出现。预计
5.1
- 如何从匹配结果中提取第一个数字
s1 = '2 Approximately 10.2 +/- 30hours'
re.findall(r"([\d. +-/]+)\s*hours|\s*hours", s)
return
['10.2 +/- 30']
期待
10.2
请注意,特殊字符 +/-.
是可选的。当出现.
如1.3
时,1.3需要和.
一起出现。但是当1 +/- 0.5
发生时,需要提取1并且应该提取+/-
中的none。
我知道我可能会做一个拆分然后取第一个数字
str(re.findall(r"([\d. +-/]+)\s*hours", s1)[0]).split(" ")[1]
给予
'10.2'
但有些结果只有return一个数字,所以拆分会导致错误。我应该用另一步完成还是可以一步完成?
请注意,这些字符串 s1
、s2
是数据框中的值。因此,需要使用 apply
和 lambda
等函数进行迭代。
事实上,我会在这里使用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')]
代码
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'...'
案例字符串:
fr'({number})(?:[\s\d\-\+\/]*)(?:{units})'
零件顺序:
- fr'({number})' - 捕获组 '(\d+[.,]?\d*)' 用于整数或浮点数
- r'(?:[\s\d-+/]*)' - 数字和单位之间允许的字符的非捕获组(即 space、+、-、数字、/)
- fr'(?:{units})' - 单位的非捕获组
目标
提取单词 hours
、hour
、day
或 days
- 如何使用
|
来匹配单词?
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
return
['5.1', '100', '1']
由于 100 和 1 不在确切的单词小时之前,因此它们不应出现。预计
5.1
- 如何从匹配结果中提取第一个数字
s1 = '2 Approximately 10.2 +/- 30hours'
re.findall(r"([\d. +-/]+)\s*hours|\s*hours", s)
return
['10.2 +/- 30']
期待
10.2
请注意,特殊字符 +/-.
是可选的。当出现.
如1.3
时,1.3需要和.
一起出现。但是当1 +/- 0.5
发生时,需要提取1并且应该提取+/-
中的none。
我知道我可能会做一个拆分然后取第一个数字
str(re.findall(r"([\d. +-/]+)\s*hours", s1)[0]).split(" ")[1]
给予
'10.2'
但有些结果只有return一个数字,所以拆分会导致错误。我应该用另一步完成还是可以一步完成?
请注意,这些字符串 s1
、s2
是数据框中的值。因此,需要使用 apply
和 lambda
等函数进行迭代。
事实上,我会在这里使用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')]
代码
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'...'
案例字符串:
fr'({number})(?:[\s\d\-\+\/]*)(?:{units})'
零件顺序:
- fr'({number})' - 捕获组 '(\d+[.,]?\d*)' 用于整数或浮点数
- r'(?:[\s\d-+/]*)' - 数字和单位之间允许的字符的非捕获组(即 space、+、-、数字、/)
- fr'(?:{units})' - 单位的非捕获组