可选组内的正则表达式提取组

Regex extract group inside optional group

我有“identfier STEP=10”形式的字符串,其中“STEP=10”部分是可选的。目标是检测有或没有 STEP 部分的两条线,并在 STEP 是线的一部分的情况下提取 STEP 的数值。现在匹配这两种情况很容易,

import re
pattern = ".*(STEP=[0-9]+)?"
re.match(pattern, "identifier STEP=10")
re.match(pattern, "identifier")

这可以毫无问题地检测到这两种情况。但是我没能一次性提取出数值。我尝试了以下,

import re
pattern = ".*(STEP=([0-9]+))?"
group0 = re.search(pattern, "identifier STEP=10").groups()
group1 = re.search(pattern, "identifier").groups()

虽然它仍然检测到线条,但我只得到

group0 = (None, None)
group1 = (None, None)

虽然我希望得到类似

的东西
group0 = (None, "10")
group1 = (None, None)

正则表达式是否不适合一次完成此操作,还是我只是用错了?我很好奇是否有一个正则表达式调用 returns 我想要的东西,而没有在我匹配该行后进行第二次传递。

可能的解决方案如下所示

import re
pattern = "^.*?(?:STEP=([0-9]+))?$"
group0 = re.search(pattern, "identifier STEP=10").groups()
group1 = re.search(pattern, "identifier").groups()
print(*group0)
print(*group1)

参见Python demo

^.*?(?:STEP=([0-9]+))?$ 正则表达式匹配

  • ^ - 字符串开头
  • .*? - 除换行字符外的零个或多个字符尽可能少(即正则表达式引擎首先跳过此模式并尝试后续模式,并且仅在后续模式时返回使用此模式匹配失败)
  • (?:STEP=([0-9]+))? - 一个可选的非捕获组:STEP= 然后第 1 组捕获一个或多个 ASCII 数字
  • $ - 字符串结尾。

.*(STEP=[0-9]+)? 正则表达式匹配如下:

  • .* - 抓取整行,从头到尾
  • (STEP=[0-9]+)? - 该组使用 * 进行量化(意味着量化模式出现 零次或多次 次),因此正则表达式引擎及其索引现在在行尾,找到匹配项:字符串末尾的空字符串,并返回匹配项,第 1 组文本值为空。

要解决此类问题,您必须了解正则表达式中的回溯(例如,请参阅 this YT video of mine 了解更多信息)。