我想从字符串中提取某些数字。问题是字符串可以包含两种不同模式的数字。如何在 re.search
中创建正则表达式模式,以便可以在单个字符串中搜索两种模式?
例如,
## extract 65.45 from this string
string = '1112 (65.45%)'
所以,如果我执行以下操作,它就会起作用
re.search('.*?\((.*)%\)', string).group(1)
我得到了预期的结果65.45
。
现在,我需要在同一文本中查找另一种字符串。
## from this string, extract 4.00 which appears before [
string = '4.00 [3.00 - 4.50]'
re.search('^(\S+)\s\[.*', string).group(1)
给了我想要的结果:4.00
但是如果我像下面这样组合它们,它只会提取第一个匹配的。
re.search('^(\S+)\s\[.*|.*?\((.*)%\)', string).group(1)
在这种情况下,只有包含方括号的字符串才会提取值,如果字符串具有 % 符号则不会提取值。我该如何解决这个问题?
例如,如果我有一个如下所示的字符串列表:
['73 (1.40%)', '38 (1.55%)', '27 (2.17%)', '32 (1.46%)', '10 (1.46%)', '11 (1.04%)', '11 (1.41%)', '7 (1.34%)', '4 (1.24%)', '28 (1.27%)', '750 (14.41%)', '381 (15.54%)', '182 (14.60%)', '313 (14.27%)', '4.10 [3.73 - 4.45]', '4.08 [3.70 - 4.42]', '4.13 [3.77 - 4.47]', '4.13 [3.78 - 4.47]', '4.07 [3.70 - 4.42]', '4.07 [3.70 - 4.43]', '4.07 [3.70 - 4.40]', '4.09 [3.73 - 4.42]', '4.03 [3.63 - 4.40]', '4.10 [3.70 - 4.47]']
我想对提取的每个值执行某些操作并与特定阈值进行比较。
使用 for 循环,我做了这样的事情:
for val in string:
match = re.search('^(\S+)\s\[.*|.*?\((.*)%\)', val)
print(match)
结果如下:
<re.Match object; span=(0, 10), match='73 (1.40%)'>
<re.Match object; span=(0, 10), match='38 (1.55%)'>
<re.Match object; span=(0, 10), match='27 (2.17%)'>
<re.Match object; span=(0, 10), match='32 (1.46%)'>
<re.Match object; span=(0, 10), match='10 (1.46%)'>
<re.Match object; span=(0, 10), match='11 (1.04%)'>
<re.Match object; span=(0, 10), match='11 (1.41%)'>
<re.Match object; span=(0, 9), match='7 (1.34%)'>
<re.Match object; span=(0, 9), match='4 (1.24%)'>
<re.Match object; span=(0, 10), match='28 (1.27%)'>
<re.Match object; span=(0, 12), match='750 (14.41%)'>
<re.Match object; span=(0, 12), match='381 (15.54%)'>
<re.Match object; span=(0, 12), match='182 (14.60%)'>
<re.Match object; span=(0, 12), match='313 (14.27%)'>
<re.Match object; span=(0, 18), match='4.10 [3.73 - 4.45]'>
<re.Match object; span=(0, 18), match='4.08 [3.70 - 4.42]'>
<re.Match object; span=(0, 18), match='4.13 [3.77 - 4.47]'>
<re.Match object; span=(0, 18), match='4.13 [3.78 - 4.47]'>
<re.Match object; span=(0, 18), match='4.07 [3.70 - 4.42]'>
<re.Match object; span=(0, 18), match='4.07 [3.70 - 4.43]'>
<re.Match object; span=(0, 18), match='4.07 [3.70 - 4.40]'>
<re.Match object; span=(0, 18), match='4.09 [3.73 - 4.42]'>
<re.Match object; span=(0, 18), match='4.03 [3.63 - 4.40]'>
<re.Match object; span=(0, 18), match='4.10 [3.70 - 4.47]'>
但不确定如何提取准确的值。
我必须执行 .group() 来提取值,但它需要我知道确切的位置。我正在努力弄清楚如何做到这一点。
如果我执行match.group(2)
,那么我会得到以下结果:
1.40
1.55
2.17
1.46
1.46
1.04
1.41
1.34
1.24
1.27
14.41
15.54
14.60
14.27
None
None
None
None
None
None
None
None
None
None
最佳答案
我只会使用简单的正则表达式列表,并针对我想要测试的每个字符串迭代它们。将使用第一个命中的正则表达式。我还会预先编译正则表达式以节省 CPU 周期。这更容易遵循可读性,并且易于添加新模式:
import re
regexs = [
re.compile(r".*?\((.*)%\)"),
re.compile(r"^(\S+)\s\[.*"),
]
data = [
"73 (1.40%)",
"38 (1.55%)",
"27 (2.17%)",
"750 (14.41%)",
"381 (15.54%)",
"4.10 [3.73 - 4.45]",
"4.08 [3.70 - 4.42]",
"4.13 [3.77 - 4.47]",
"this shouldn't match"
]
for val in data:
for regex in regexs:
if match := regex.search(val):
print("Matched: " + match.group(1))
break
else:
print("No match: " + val)
输出:
Matched: 1.40
Matched: 1.55
Matched: 2.17
Matched: 14.41
Matched: 15.54
Matched: 4.10
Matched: 4.08
Matched: 4.13
No match: this shouldn't match
关于python - 有没有办法在正则表达式 python 中检查同一字符串中的两种不同模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67552770/