首页 > 解决方案 > Python 正则表达式在分隔符之间重复捕获的组

问题描述

我正在尝试捕获某些定界符之间的重复模式。字符串是这样的 -

block 1
   <some other text here>
   element 1
   element 2
   element 3
   <some other text here>
   <some other text here>
exit
block 2
   <some other text here>
   element 1
   element 2
   <some other text here>
   <some other text here>
exit

我想捕获块 id 以及其中的元素。每个块的元素数量可能不同,但结构是相同的。使用 python 正则表达式。PS,我不想使用 re.findall 或 split。数据并非一直如此结构化。这是一个大块中的模式,我试图了解如何多次重复正则表达式的一部分并捕获所有匹配项。我试过这个 - 块 (\d+)(?:.|\n) ?((?:element (\d+)\n)+)(?:.|\n) ?\s+exit 但这仅捕获所有块中的第一个元素。请帮助 regex101 链接

标签: pythonregex

解决方案


由于您的块包含任意数量的元素,因此re.search()用于捕获组的带括号的函数将不适用。如果您不想使用re.findall(),一个很好的替代方法是使用re.finditer(). 请您尝试以下方法:

import re

str = '''
block 1
   <some other text here>
   element 1
   element 2
   element 3
   <some other text here>
   <some other text here>
exit
block 2
   <some other text here>
   element 1
   element 2
   <some other text here>
   <some other text here>
exit
'''

for m1 in re.finditer(r'(block \d+.*?exit)', str, re.DOTALL):
    for m2 in re.finditer(r'(block \d+|element \d+)', m1.group(1)):
        print(m2.group(1))
    print('')           # just to put an empty line between blocks

输出:

block 1
element 1
element 2
element 3

block 2
element 1
element 2

如果要使用匹配结果创建列表列表,可以将代码的后半部分修改为:

blocks = []
for m1 in re.finditer(r'(block \d+.*?exit)', str, re.DOTALL):
    elements = []
    for m2 in re.finditer(r'(block \d+|element \d+)', m1.group(1)):
        elements.append(m2.group(1))
    blocks.append(elements)

for bl in blocks:
    for el in bl:
        print(el)

推荐阅读