使用.net正则表达式平衡匹配捕获内部项目

前端之家收集整理的这篇文章主要介绍了使用.net正则表达式平衡匹配捕获内部项目前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在.net Regexes的平衡匹配上找到了以下资源:

> http://weblogs.asp.net/whaggard/archive/2005/02/20/377025.aspx
> http://blogs.msdn.com/bclteam/archive/2005/03/15/396452.aspx
> http://msdn.microsoft.com/en-us/library/bs2twtah(VS.85).aspx#BalancingGroupDefinitionExample

根据我在这些中读到的内容,以下示例应该有效:

这个正则表达式应该在一个角括号组中的任何地方找到一个“a”,无论多深.它应匹配“< a>”,“<<>>”,“<<> a>”,“<<<> < a>>“等

(?<=
    ^
    (
        (
            <(?<Depth>)
            |
            >(?<-Depth>)
        )
        [^<>]*?
    )+?
)
(?(Depth)a|(?!))

匹配字符串“<<> a>”中的“a”

虽然它适用于字符串“< a<>>”和“<<>>”,我不能让它匹配“>”之后的“a”.

根据我读过的解释,前两个“<”s应该增加深度两次,然后是第一个“>”应该减少一次.此时,(?(深度)a |(?!))应执行“是”选项,但正则表达式从未在此处进行.

考虑以下正则表达式,它没有进行这样的检查,仍然无法匹配有问题的字符串:

(?<=
    ^
    (
        (
            <(?<Depth>)
            |
            >(?<-Depth>)
        )
        [^<>]*?
    )+?
)
a

我错过了什么,或者正则表达式引擎是否正常工作?

解决方法

如果你想找到一对平衡括号内的每一个’a’,我会建议这种方法

Regex r = new Regex(@"
    <
      (?>
         [^<>a]+
       |
         (a)
       |
         <(?<N>)
       |
         >(?<-N>)
      )+
    (?(N)(?!))
    >
",RegexOptions.IgnorePatternWhitespace);
string target = @"012a<56a8<0a2<4a6a>>012a<56789a>23456a";
foreach (Match m in r.Matches(target))
{
  Console.WriteLine("{0},{1}",m.Index,m.Value);
  foreach (Capture c in m.Groups[1].Captures)
  {
    Console.WriteLine("{0},c.Index,c.Value);
  }
}

结果:

9,<0a2<4a6a>>
11,a
15,a
17,a
24,<56789a>
30,a

它不是与条件相关,而是匹配整个括号分隔(子)字符串,捕获它可能包含的任何一个.与您的方法不同,它可以从更大的字符串中提取任意数量的括号中的子字符串,并从每个子字符串中提取任意数量的字符串.

猜你在找的正则表达式相关文章