RegEx:如何捕获子节
本文关键字:何捕获 RegEx | 更新日期: 2023-09-27 18:04:26
考虑以下简单的文本信息:
info
start
date=20140521
val=key1
info="Just a string"
end
start
date=20140521
val=key2
info="Another one"
end
end
我想使用RegEx捕获基于'val'字段值的部分。
为了方便示例,假设我想获得val=key1 section。
后面的正则表达式没有捕获任何东西!
(start((?=val=key1)(.|'s))*?end)
然而,如果我使用下面的一个,我可以捕获val=key2的部分(与我想要的相反)
(start((?!val=key1)(.|'s))*?end)
下面是本例中捕获的部分:
start
date=20140521
val=key2
info="Another one"
end
有简单的方法吗?
如果您想忽略除val=1
以外的部分,您可以在这里使用以下命令。
(?s)(start((?!val='d+).)*val=1'b.*?end)
现场演示
:
要回答更新的编辑,您可以使用以下命令捕获这些部分。
正则表达式:(?s)(start((?!val='w+).)*val=key1'b.*?end)
(?s) set flags for this block (with . matching 'n) ( group and capture to '1: start 'start' ( group and capture to '2 (0 or more times) (?! look ahead to see if there is not: val= 'val=' 'w+ word characters (a-z, A-Z, 0-9, _) (1 or more times) ) end of look-ahead . any character )* end of '2 val=key1 'val=key1' 'b the boundary between a word char ('w) and not a word char end 'end' ) end of '1
现场演示
如果你只是想找到start's+val=1
和end
之间的东西,你可以使用一些简单的东西,如:
(?s)'bstart's+val=1'b(.*?)'bend'b
您可以将val=1
替换为您感兴趣的任何模式
您遇到的问题(示例输入没有捕捉到)是,在您想要的开始/结束块之前有一个开始/结束块,因为一个朴素的正则表达式,即使使用不情愿的量词,也会在目标值之前的第一个开始匹配。
解决方案是在匹配之前消耗尽可能多的输入:
.*(start.*?val=1'b.*?end)
查看实时演示,它在目标之前有一个额外的块,它被捕获为组1。
这个正则表达式必须与"dotall"标志一起使用,它将目标块捕获为第1组。"。*"在前面是一个很小但很重要的部分,它消耗你的目标前面的所有block。
如果需要的话,您可以通过在各个部分周围设置单词边界'b
来更加严格。但是,建议在目标数字之后设置单词边界,这样像val=12
这样的输入就不会意外匹配。