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

C# 正则表达式捕获括号组,包括内括号和外括号,c#,.net,regex,C#,.net,Regex,我想匹配所有括号,包括内括号和外括号 输入:abc(测试)def(rst(另一测试)uv)xy 所需输出:(测试) (rst(另一项测试)紫外线) (另一项测试) 我下面的c代码只返回(test)和(rst(另一个测试)uv): string input=“abc(测试)定义(rst(另一测试)uv)xy”; Regex Regex=new Regex(@“\([^()]+\(?\())+(?\)+(?(Level)(?!)\)”,RegexOptions.IgnorePatternWhites

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

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

所需输出:(测试)

(rst(另一项测试)紫外线)

(另一项测试)

我下面的c代码只返回
(test)
(rst(另一个测试)uv)

string input=“abc(测试)定义(rst(另一测试)uv)xy”;
Regex Regex=new Regex(@“\([^()]+\(?\())+(?\)+(?(Level)(?!)\)”,RegexOptions.IgnorePatternWhitespace);
foreach(正则表达式中的匹配c.Matches(输入))
{
控制台写入线(c值);
}

编辑:这个答案对于.Net正则表达式来说完全是错误的-请参见下面的nam评论

原始答复:

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


你可以使用这个:
\((?>[^()]+\124;\((?)(?)*(?(p)(?!)\)
但是你必须通过捕获、组和组的捕获来获得你想要的(请参见)

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

Regex regex = new Regex(@"(?=(\(([^()]+| (?<Level>\()| (?<-Level>\)))+(?(Level)(?!))\)))", RegexOptions.IgnorePatternWhitespace);
结果:
(测试)
(rst(另一测试)uv)
(另一测试)

请注意,未编排的正向look ahead可用于查找与就地捕获重叠的匹配,因为它们不使用文本(即,当尝试与lookahead中的所有子模式匹配时,正则表达式引擎索引保持在其当前位置)并且正则表达式引擎在匹配/失败后自动移动其索引,使匹配过程“全局”(即在输入字符串中的每个位置测试匹配)

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


因此,当对
)进行前瞻时,它可能会匹配一个零宽度字符串,并将您需要的值放入组1。然后,它继续并在第一个
(…)中找到另一个
,并且可以再次捕获其中的子字符串。

我正在使用支持的.NET正则表达式。它可以工作。如果我还有问题,我将发表评论。感谢您简要解释您的解决方案,因为它帮助我更好地理解未来的使用。我使用手机发布了我的答案,现在只能修复拼写错误。我添加了解释还有一个演示代码。很高兴它能为您工作。您建议的模式不适用于Regex.Replace(…)方法。我可能缺少一些东西,或者它可能与您在帖子中提到的Regex引擎索引有关。例如,
input=Regex.Replace(st,@“(?=([^()])+(124;(?\())+((Level)(!)\)”,delegate(匹配){return'['+match.Groups[1].Value+']';});
给出一个奇数输出:
abc[(test)](test)def[(rst(另一个测试)uv)](rst[(另一个测试)](rst def[(rst(另一个测试))uv](rst[(另一个测试)](rst uv xy
而不是
abc[(test def[(rst[(rst[(另一个测试)]uvxy
我认为您误解了替换如何与空字符串匹配。由于它不使用字符,您只需在捕获的文本之前替换空字符串即可。添加更多代码:首先,获取需要替换的字符串,然后在foreach循环中手动替换。您最终成功了吗?如果没有,请告诉我知道。
Regex regex = new Regex(@"(?=(\(([^()]+| (?<Level>\()| (?<-Level>\)))+(?(Level)(?!))\)))", RegexOptions.IgnorePatternWhitespace);
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));
    }
}