如何在Python的正则表达式中组合匹配组?

3
如何在以下代码中合并组(p1 和 p2)?
import re

txt = "Sab11Mba11"
p1 = "(S(a|b)(a|b))"
p2 = "(M(a|b)(a|b))"
px = "(" + p1 + '|' + p2 + ")"

print(re.findall(p1, txt)) # [('Sab', 'a', 'b')]
print(re.findall(p2, txt)) # [('Mba', 'b', 'a')]
print(re.findall(px, txt)) # [('Sab', 'Sab', 'a', 'b', '', '', ''), ('Mba', '', '', '', 'Mba', 'b', 'a')]

请解释为什么我会得到空字符串,以及如何获得 [('Sab','a','b'),('Mba','b','a')]

2个回答

1
您可以尝试使用分支重置组。这需要使用PyPi的正则表达式模块:
import regex as re

txt = 'Sab11Mba11'
p1 = r'(S(a|b)(a|b))'
p2 = r'(M(a|b)(a|b))'

px = r'(?|' + p1 + '|' + p2 + ')'
print(re.findall(px, txt))

输出:

[('Sab', 'a', 'b'), ('Mba', 'b', 'a')]

分组数字将在分支重置的不同分支之间被重复使用。

一般来说,在处理正则表达式时,不要忘记使用原始字符串表示法,假设Sab是其他结构的占位符。此外,请注意,如果您使用f-string构造,则不需要'px'本身。例如:

re.findall(fr'(?|{p1}|{p2})', txt)

1
没有参与匹配的捕获组的空值仍然被输出。你需要去掉外部括号并过滤掉结果元组中的空值。
import re

txt = "Sab11Mba11"
p1 = "(S(a|b)(a|b))"
p2 = "(M(a|b)(a|b))"
px = p1 + '|' + p2
print([tuple(filter(lambda m: m != '', x)) for x in re.findall(px, txt)])
# => [('Sab', 'a', 'b'), ('Mba', 'b', 'a')]

查看Python演示


sub的情况下,我应该使用相同的方法(过滤空字符串)吗?例如:`def repl(x): c = list(filter(lambda m: m != None, x.groups())) return c[2] + c[1] re.sub(px, repl, txt)` - Oleg Dats
@OlegDats 如果那是你需要的,为什么不呢? - Wiktor Stribiżew
我希望能够在不需要过滤的情况下获取对象。在我的情况下,性能非常重要。我的真正任务包括更多的情况和更长的字符串。每次都进行过滤是不高效的。 - Oleg Dats
@OlegDats 这里没有其他办法,我在答案的顶部解释了原因。 - Wiktor Stribiżew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接