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

Pau*_*ams 4 .net regex

我在.net Regexes的平衡匹配上找到了以下资源:

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

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

(?<=
    ^
    (
        (
            <(?<Depth>)
            |
            >(?<-Depth>)
        )
        [^<>]*?
    )+?
)
(?(Depth)a|(?!))
Run Code Online (Sandbox Code Playgroud)

匹配字符串"<<> a>"中的"a"

虽然它适用于字符串" <a<>>"和" <<a>>",但我无法使其与">"之后的"a"相匹配.

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

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

(?<=
    ^
    (
        (
            <(?<Depth>)
            |
            >(?<-Depth>)
        )
        [^<>]*?
    )+?
)
a
Run Code Online (Sandbox Code Playgroud)

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

Ala*_*ore 5

如果你想找到'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}, {1}", c.Index, c.Value);
  }
}
Run Code Online (Sandbox Code Playgroud)

结果:

9, <0a2<4a6a>>
11, a
15, a
17, a
24, <56789a>
30, a
Run Code Online (Sandbox Code Playgroud)

它不是用条件进行捣乱,而是在捕获任何a可能包含的任何内容的过程中匹配整个括号分隔(子)字符串.与您的方法不同,它可以从更大的字符串中提取任意数量的括号中的子字符串,并a从每个子字符串中提取任意数量的子字符串.