正则表达式与可选的文本块

时间:2016-04-19 07:17:07

标签: python regex parsing

我使用正则表达式来解析结构化文本,如下所示,插入符号标记我想要匹配的内容:

block 1
^^^^^^^
    subblock 1.1
        attrib a=a1
    subblock 1.2
        attrib b=b1
                 ^^
block 2
    subblock 2.1
        attrib a=a2
block 3
^^^^^^^
    subblock 3.1
        attrib a=a3
    subblock 3.2
        attrib b=b3
                 ^^

子块可能出现在块内,也可能不出现在块内,例如:子块2.2

预期的匹配是 [(block1,b1),(block3,b3)]

/(capture block#)[\s\S]*?attrib\sb=(capture b#)/gm

但最终匹配 [(block1,b1),(block2,b3)]

我在哪里做正则表达式错误?

2 个答案:

答案 0 :(得分:2)

您可以使用

(?m)(^block\s*\d+).*(?:\n(?!block\s*\d).*)*\battrib\s*b=(\w+)

请参阅the regex demo

正则表达式基于展开循环技术。这是一个解释:

  • (?m) - 使^匹配行的开头的多行修饰符
  • (^block\s*\d+) - 匹配并捕获block +可选空格+ 1+位数(第1组)
  • .* - 匹配行的其余部分(因为不应该启用DOTALL选项)
  • (?:\n(?!block\s*\d).*)* - 匹配之后的任何文字都不是单词block,后跟可选的空格后跟数字(这样就设置了边界)
  • \battrib\s*b=(\w+) - 匹配整个单词attrib,后跟0 +空格,文字b=,匹配并捕获1 +字母数字或下划线( note :可以根据您的真实数据进行调整(\w+)

Python demo

import re
p = re.compile(r'(?m)(^block\s*\d+).*(?:\n(?!block\s*\d).*)*\battrib\s*b=(\w+)')
s = "block 1\n    subblock 1.1\n        attrib a=a1\n    subblock 1.2\n        attrib b=b1\nblock 2\n    subblock 2.1\n        attrib a=a2\nblock 3\n    subblock 3.1\n        attrib a=a3\n    subblock 3.2\n        attrib b=b3"
print(p.findall(s))

答案 1 :(得分:0)

这个正则表达式怎么样? https://regex101.com/r/yZ4fL9/1

block (\d).*?attrib b=b(\1)