正则表达式捕获括号组,包括内括号和外括号

时间:2015-11-15 01:42:28

标签: c# .net regex

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

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

期望输出 :(测试)

(rst(另一个测试)uv)

(另一项测试)

我的以下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);
}

3 个答案:

答案 0 :(得分:1)

您正在寻找重叠匹配。因此,只需将正则表达式放入捕获组并将其置于非锚定的正向前瞻中:

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

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

请参阅IDEONE demo

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)

请注意,非锚定的正向前瞻可用于查找重叠匹配,因为它们不消耗文本(即正则表达式引擎索引在尝试匹配时保持在当前位置)前瞻中的所有子模式)和正则表达式引擎在匹配/失败后自动移动其索引,从而使匹配过程&#34;全局&#34; (即在输入字符串内的每个位置测试匹配)。

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

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

答案 1 :(得分:0)

编辑:对于.Net正则表达式,这个答案是错误的 - 请参阅下面的nam评论。

原始答案:

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

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

答案 2 :(得分:0)

你可以使用这个:\((?>[^()]+|\((?<P>)|(?<C-P>)\))*(?(P)(?!))\),但你必须深入挖掘捕获,群组和群组。捕获以获得您想要的内容(请参阅demo