假设我有正则表达式(?:AA|BB)(.*)(?:AA|BB),它捕获分隔符AA和.之间的所有内容BB
我遇到的问题是这也会匹配 AA...BB
我怎样才能使正则表达式只匹配AA...AA和BB...BB
如果您需要匹配开头和结尾的字符串与相同的前导和尾随分隔符,您只需要捕获前导分隔符并在模式本身内部使用反向引用:
(AA|BB)(.*)\1
^ ^ ^^
Run Code Online (Sandbox Code Playgroud)
请参阅正则表达式演示
在Python中,re.finditer如果您只想获得所需的组,则必须使用,而不是re.findall返回元组列表(因此将包含AA或BB).要匹配AA直到第一个下一个的子字符串AA,请使用延迟量词*?:(AA|BB)(.*?)\1
一个简短的Python演示:
import re
p = re.compile(r'(AA|BB)(.*)\1')
test_str = "AA text AA"
print([x.group(2).strip() for x in p.finditer(test_str)])
# => ['text']
Run Code Online (Sandbox Code Playgroud)
如果需要匹配前导和尾随分隔符不匹配的字符串,则必须使用替换:
AA(.*)AA|BB(.*)BB
Run Code Online (Sandbox Code Playgroud)
或者 - 一个懒惰的量词版本,以匹配最接近的尾随AAs和BBs:
AA(.*?)ZZ|BB(.*?)YY
Run Code Online (Sandbox Code Playgroud)
请注意,这将在结果中输出空元素,因为只匹配一个组.在大多数Python构建中,如果您计划使用此模式,则应谨慎使用此模式re.sub(直到Python 3.5,未匹配的组未使用空字符串(= None)初始化)并可能引发异常.
下面是一个提取样本代码与re.finditer:
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)])
Run Code Online (Sandbox Code Playgroud)
结果:
Contents:
['Text 1 here']
['Text2 there']
Delimiters:
[('AA', 'ZZ')]
[('BB', 'YY')]
Run Code Online (Sandbox Code Playgroud)
在现实生活中,使用非常长而复杂的文本,可以展开这些正则表达式以使匹配线性和高效,但这是一个不同的故事.
最后但并非最不重要的是,如果您需要将最短的子字符串从一个分隔符匹配到另一个不包含这些分隔符的子字符串,请使用一个淬火的贪婪令牌:
AA((?:(?!AA|ZZ).)*)ZZ|BB((?:(?!BB|YY).)*)YY
^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)
请参阅正则表达式演示以查看与...的区别AA(.*?)ZZ|BB(.*?)YY.
| 归档时间: |
|
| 查看次数: |
283 次 |
| 最近记录: |