此post显示了如何使用正则表达式找到最短重叠匹配。 One of the answers显示了如何获得最短的匹配,但我正在努力解决如何找到最短匹配和标记其位置,或替换用另一个字符串。
所以在给定的模式中,
A|B|A|F|B|C|D|E|F|G
我要找到的模式是:
my_pattern = 'A.*?B.*?C'
如何识别最短匹配并在原始给定模式中标记如下?
A|B|[A|F|B|C]|D|E|F|G
或替代:
A|B|AAA|F|BBB|CCC|D|E|F|G
答案 0 :(得分:2)
我建议Tim Pietzcker's answer使用re.sub
:
>>> p=re.findall(r'(?=(A.*?B.*?C))',s)
>>> re.sub(r'({})'.format(re.escape(min(p, key=len))),r'[\1]',s,re.DOTALL)
'A|B|[A|F|B|C]|D|E|F|G'
答案 1 :(得分:2)
一种方法是在A
和B
之间使用前瞻,然后在B
和C
之间使用这样的前瞻:
import re
p = re.compile(ur'A(?:(?![AC]).)*B(?:(?![AB]).)*C')
test_str = u"A|B|A|F|B|C|D|E|F|G"
result = re.sub(p, u"[$0]", test_str)
# A|B|[A|F|B|C]|D|E|F|G
test_str = u"A|B|C|F|B|C|D|E|F|G"
result = re.sub(p, u"[$0]", test_str)
# [A|B|C]|F|B|C|D|E|F|G
答案 2 :(得分:1)
(A[^A]*?B[^B]*?C)
您可以使用[\1]
这个简单的regex.Replace。
x="A|B|A|F|B|C|D|A|B|C"
print re.sub("("+re.escape(min(re.findall(r"(A[^A]*?B[^B]*?C)",x),key=len))+")",r"[\1]",x)