Regex,匹配以)结尾的字符串,并忽略中间的任何()

本文关键字:中间 任何 字符串 结尾 Regex | 更新日期: 2023-09-27 18:26:41

我想选择字符串的一部分,但问题是我想选择的最后一个字符可能会多次出现。

我想选择'Aggregate('并在匹配的')'处结束,介于两者之间的任何()都可以忽略。

示例:

string:Substr(Aggregate(SubQuery,SUM,[Model].Rea备注*[Object].Shortname+10),0,1)
应返回:Aggregate(SubQuery,SUM,[Model].Eremark*[Object].Shortname+10)

string:Substr(Aggregate(SubQuery,SUM,[Model].Remark*([Object].Shortname+10)),0,1)
应返回:Aggregate(SubQuery,SUM,[Model].Eremark*([Object].Shortname+10))

string:Substr(Aggregate(SubQuery,SUM,([Model].Eremark)*([Object].Shortname+10)),0,1)
应返回:聚合(SubQuery,SUM,([Model].Remont)*([Object].Shortname+10))

有没有一种方法可以用正则表达式来解决这个问题?我正在使用C#。

Regex,匹配以)结尾的字符串,并忽略中间的任何()

这有点难看,但您可以使用类似的东西

Aggregate'(([^()]+|'(.*?'))*')

它通过了您的所有测试,但它只能匹配一个级别的嵌套圆括号。

此解决方案通过使用.NET平衡组来处理任何级别的嵌套括号:

(?x)              # allow comments and ignore whitespace
Aggregate'(
(?:
  [^()]           # anything but ( and )
| (?<open> '( )   # ( -> open++
| (?<-open> ') )  # ) -> open--
)*
(?(open) (?!) )   # fail if open > 0
')


我不确定输入的变化有多大,但对于问题中的字符串示例,像这样简单的东西会起作用:

Aggregate'(.*')(?=,)

如果最终考虑避免使用正则表达式,这里有一个解析的替代方案,它使用System.Xml.Linq命名空间:

class Program
{
    static void Main()
    {
        var input = File.ReadAllLines("input.txt");
        input.ToList().ForEach(item => {
            Console.WriteLine(item.GetParameter("Aggregate"));
        });
    }
}
static class X
{
    public static string GetParameter(this string expression, string element)
    {
        XDocument doc;
        var input1 = "<root>" + expression
            .Replace("(", "<n1>")
            .Replace(")", "</n1>")
            .Replace("[", "<n2>")
            .Replace("]", "</n2>") +
            "</root>";
        try
        {
            doc = XDocument.Parse(input1);
        }
        catch
        {
            return null;
        }
        var agg=doc.Descendants()
            .Where(d => d.FirstNode.ToString() == element)
            .FirstOrDefault();
        if (agg == null)
            return null;
        var param = agg
            .Elements()
            .FirstOrDefault();
        if (param == null)
            return null;
        return element +
            param
            .ToString()
            .Replace("<n1>", "(")
            .Replace("</n1>", ")")
            .Replace("<n2>", "[")
            .Replace("</n2>", "]");
    }
}

此正则表达式适用于任何数量的括号对,并嵌套到任何级别:

Aggregate'(([^(]*'([^)]*'))*[^()]')

例如,它会在这里找到粗体文本:

Substr(Aggregate(SubQuery,SUM(foo(bar),baz()),([Model].Remory)*([Object].Shortname+10)),0,1)

请注意其中的SUM(foo(bar), baz())

在rubular上观看现场演示。