import re
p = re.compile(r'(AA)(.*?)(ZZ)|(BB)(.*?)(YY)')
test_str = "AA Text 1 here ZZ and BB Text2 there YY"
print("Contents:")
print([x.group(2).strip() for x in p.finditer(test_str) if x.group(2)])
print([x.group(5).strip() for x in p.finditer(test_str) if x.group(5)])
print("Delimiters:")
print([(x.group(1), x.group(3)) for x in p.finditer(test_str) if x.group(1) and x.group(3)])
print([(x.group(4), x.group(6)) for x in p.finditer(test_str) if x.group(4) and x.group(6)])
>>> data = ['AAsometextAA', 'BBothertextBB', 'NotMatched', 'AAalsonotmatchedBB']
>>> matches = filter(lambda x: x is not None, [re.match("(?:(AA(.*)AA)|(BB(.*)BB))", datum) for datum in data])
>>> matches
[<_sre.SRE_Match object at 0x007DC078>, <_sre.SRE_Match object at 0x007DC288>]
>>> for match in matches:
... print(match.group(0))
...
AAsometextAA
BBothertextBB
>>>
4条答案
按热度按时间utugiqy61#
如果需要匹配的字符串的开头和结尾具有*相同的 * 前导和尾随分隔符,则只需捕获前导分隔符并在模式本身内部使用 * 反向引用 *:
参见regex demo
在Python中,如果你只想得到你需要的组,你就必须使用
re.finditer
,而不是返回元组列表(因此包含AA
或BB
)的re.findall
,为了匹配从AA
到下一个AA
的子字符串,使用惰性量词*?
:(AA|BB)(.*?)\1
一个简短的Python demo:
如果需要匹配带有不匹配的前导和尾随分隔符的字符串,则必须使用alternation:
或者-匹配最接近的尾随
AA
s和BB
s的惰性限定符版本:注意,这将在结果中输出空元素,因为只有一个组会被匹配,在大多数Python构建中,如果你计划在
re.sub
中使用这种模式,应该谨慎使用(在Python 3.5之前,不匹配的组不会用空字符串(= None)初始化,并且可能抛出异常。下面是一个带有
re.finditer
的extraction sample code:结果:
在现实生活中,对于非常长和复杂的文本,这些正则表达式可以是unrolled,以使匹配线性和高效,但这是一个不同的故事。
最后但并非最不重要的是,如果您需要将最短的子字符串从一个分隔符匹配到另一个分隔符,而该分隔符在中不包含这些分隔符,请使用tempered greedy标记:
请参见regex demo以了解与
AA(.*?)ZZ|BB(.*?)YY
的区别。k2fxgqgv2#
这个问题让人困惑。据我所知,您希望它匹配AA..AA或BB..BB,但不匹配当前匹配的AA..BB。我对正则表达式很不在行,但我认为这应该可以工作:
编辑:抱歉,SE格式搞砸了。
uhry853o3#
这应该对你有用。
ct3nt3jp4#
试试这个
查看this示例