Regex捕获括号组,包括内括号和外括号

  • 本文关键字:包括内 Regex c# .net regex
  • 更新时间 :
  • 英文 :


我想匹配所有括号,包括内括号和外括号。

输入:abc(测试)def(rst(另一个测试)uv)xy

所需输出:(测试)

(第一次(另一次测试)紫外线)

(另一项测试)

我下面的c#代码只返回(test)(rst(another test)uv):

string input = "abc(test)def(rst(another test)uv)xy";
Regex regex = new Regex(@"(([^()]+| (?<Level>()| (?<-Level>)))+(?(Level)(?!)))", RegexOptions.IgnorePatternWhitespace);
foreach (Match c in regex.Matches(input))
{
    Console.WriteLine(c.Value);
}

您正在寻找重叠的匹配。因此,只需将regex放入一个捕获组中,并将其放入一个非锚定的正向前瞻:

Regex regex = new Regex(@"(?=((([^()]+| (?<Level>()| (?<-Level>)))+(?(Level)(?!)))))", RegexOptions.IgnorePatternWhitespace);

您需要的值将在match.Groups[1].Value中。

查看IDEONE演示:

using System;
using System.Text.RegularExpressions;
using System.IO;
using System.Linq;
public class Test
{
    public static void Main()
    {
        var input = "abc(test)def(rst(another test)uv)xy";
        var regex = new Regex(@"(?=((([^()]+| (?<Level>()| (?<-Level>)))+(?(Level)(?!)))))", RegexOptions.IgnorePatternWhitespace);
        var results = regex.Matches(input).Cast<Match>()
                       .Select(p => p.Groups[1].Value)
                       .ToList();
        Console.WriteLine(String.Join(", ", results));
    }
}

结果:(test)(rst(another test)uv)(another test)

请注意,未固定的正向外观ahead可用于在捕获到位的情况下查找重叠的匹配,因为它们不消耗文本(即,当试图与前瞻内的所有子模式匹配时,正则表达式引擎索引保持在其当前位置),并且正则表达式引擎在匹配/失败后自动移动其索引,使匹配过程"全局"(即在输入字符串内的每个位置测试匹配)。

尽管前瞻子表达式不匹配,但它们仍然可以捕获到组中。

因此,当展望(时,它可能会匹配一个零宽度字符串,并将它们的值放入组1中。然后,它继续并在第一个(...)中找到另一个(,并可以再次捕获其中的子字符串。

您可以使用这个:((?>[^()]+|((?<P>)|(?<C-P>)))*(?(P)(?!))),但您必须深入了解捕获、组和组的捕获,才能获得您想要的(请参阅演示)

Edit:对于.Net正则表达式,这个答案完全错误-请参阅下面nam的注释。

原始答案:

正则表达式与正则语言匹配。嵌套圆括号不是一种常规语言,它们需要上下文无关的语法来匹配。所以简单的答案是没有办法做你正在尝试的事情。

https://stackoverflow.com/a/133684/361631

最新更新