【问题标题】:Python regex to repeat a captured group between delimitersPython正则表达式在分隔符之间重复捕获的组
【发布时间】:2021-10-18 15:01:58
【问题描述】:

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

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 正则表达式。 P.S.,我不想使用 re.findall 或 split。数据并非一直如此结构化。这是一个大块中的模式,我试图了解如何多次重复正则表达式的一部分并捕获所有匹配项。 我试过这个 - 块 (\d+)(?:.|\n)?((?:element (\d+)\n)+)(?:.|\n)?\s +退出 但这仅捕获所有块中的第一个元素。请帮忙 regex101 link

【问题讨论】:

  • 您能否添加一两个示例输入字符串和预期的捕获数据。
  • 预期捕获的数据 - 组 1:块 1,组 2:元素 1,组 3:元素 2,组 4:元素 3....匹配 1 应该有第一个块退出。匹配 2 应该有第二个块及其相应的元素
  • 是否需要正则表达式?
  • @AvinashRaj 是正确的。如果数据已经像给定的示例那样结构良好,则无需正则表达式即可轻松完成。
  • 我不想使用 split 或 findall。还有一些组合需要满足。这只是整个文件中的一种模式

标签: python regex


【解决方案1】:

由于您的块包含任意数量的元素,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)

【讨论】:

  • (你也可以使用非捕获组 :-) ideone.com/aIr7YJ
  • @Thefourthbird 非常感谢您的建议!干杯。
猜你喜欢
  • 2022-01-22
  • 2020-04-06
  • 2020-12-11
  • 1970-01-01
  • 2016-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多