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+)
,后跟0+空格、文字attrib
,然后匹配并捕获1+字母数字或下划线(注意:这可以根据实际数据进行调整)和b=
(\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))