python - 有没有办法在正则表达式 python 中检查同一字符串中的两种不同模式?

标签 python regex

我想从字符串中提取某些数字。问题是字符串可以包含两种不同模式的数字。如何在 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/

相关文章:

python - 打开图像的最佳方式?

python - 使用 lambda 时索引超出范围

python - 如何将 itertools.permutations ("0123456789") 的结果(在 python 中)转换为字符串列表

regex - 需要 .h 或 .cpp 的正则表达式

mysql - 求助MySQL正则表达式——抢年头

python - os.listdir 看不到我的目录

python - 有没有办法传入一个参数来匹配neo4j中的标签

regex - 使用 Regex 和 AltSearch 删除空行

python - 验证日期(格式和值)

Java replaceAll 正则表达式从 XML 中读取