Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 带有可选文本块的正则表达式_Python_Regex_Parsing - Fatal编程技术网

Python 带有可选文本块的正则表达式

Python 带有可选文本块的正则表达式,python,regex,parsing,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 s

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

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

预期匹配为[(区块1,b1),(区块3,b3)]

但这最终匹配[(区块1,b1),(区块2,b3)]

我的正则表达式哪里做错了?

这个正则表达式呢

你可以用

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

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

  • (?m)
    -使
    ^
    与行首匹配的多行修饰符
  • (^block\s*\d+)
    -匹配并捕获
    +可选空格+1+数字(组1)
  • *
    -与行的其余部分匹配(因为不应启用任何DOTALL选项)
  • (?:\n(?!block\s*\d)。*)*
    -匹配后面不是单词的任何文本
    ,后跟可选空格和数字(这样,设置了边界)
  • \battrib\s*b=(\w+)
    -匹配整个单词
    attrib
    ,后跟0+空格、文字
    b=
    ,然后匹配并捕获1+字母数字或下划线(注意:这可以根据实际数据进行调整)和
    (\w+)
:


您总是需要子块的
b
属性吗?你能不能也为这句话提供一个完整的例子。。。。子块可能出现在块内部,也可能不出现在块内部。。。那里的预期输出是什么?什么是(捕获b#)?@AKS Yes始终需要“b”属性。如果应该包含此属性的子块在特定块中不存在,我只想跳过该块并转到下一个块。在上面的示例中,block2没有子block2.2,它将包含属性“b”。所以我就放弃了这个块。@WiktorStribiżew By(capture b#)我指的是在capture组中选择值“b#”的正则表达式。在上面的示例中,只需(\D\D)。但是属性的值可能需要复杂的正则表达式本身。已经命中&尝试负前瞻。谢谢你的正确语法!仅供参考:未展开的正则表达式版本是(使用一个标记)。它更具可读性,但效率不高。
block (\d).*?attrib b=b(\1)
(?m)(^block\s*\d+).*(?:\n(?!block\s*\d).*)*\battrib\s*b=(\w+)
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))