RegEx:如何捕获子节

时间:2014-05-21 21:53:58

标签: c# .net regex

考虑以下简单的文字信息:

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

这样做的简单方法是什么?

3 个答案:

答案 0 :(得分:2)

如果您想忽略val=1以外的部分,可以在此处使用以下部分。

(?s)(start((?!val=\d+).)*val=1\b.*?end)

Live Demo

更新

  • 要回答更新的编辑,您可以使用以下内容来捕获这些部分。

    (?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
    

    Live Demo

答案 1 :(得分:0)

如果您只想查找start\s+val=1end之间的内容,可以使用以下简单的内容:

(?s)\bstart\s+val=1\b(.*?)\bend\b

您可以用您感兴趣的任何模式替换val=1

答案 2 :(得分:0)

你所遇到的问题,即示例输入未捕获的问题,是在你想要的那个之前有一个开始/结束块,因为一个天真的正则表达式,即使使用不情愿的量词,也会在第一次启动之前匹配目标值。

解决方案是在匹配之前消耗尽可能多的输入:

.*(start.*?val=1\b.*?end)

参见live demo,它在目标之前有一个额外的块,它被捕获为第1组。

这个正则表达式,必须与" dotall"一起使用。 flag,将您的目标块捕获为组1."。*"在前面是一个小而重要的部分,消耗可能在你的目标之前的任何块。

如果需要,可以通过在各个部分周围添加单词边界\b来更加严格。可能会在目标编号之后建议字边界,因此val=12之类的输入不会意外匹配。