正则表达式,匹配以?结尾的字符串,并忽略其中的任何()

时间:2013-08-07 13:14:20

标签: c# regex

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

我想选择'Aggregate('并以匹配的')'结束,可以忽略其间的任何()

示例:

  

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

     

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

     

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

有没有办法用正则表达式来解决这个问题?我正在使用C#。

4 个答案:

答案 0 :(得分:3)

这有点难看,但你可以使用像

这样的东西
Aggregate\(([^()]+|\(.*?\))*\)

它会传递所有测试,但它只能匹配一级嵌套括号。

答案 1 :(得分:1)

此解决方案使用.NETs balancing groups

与任何级别的嵌套括号一起使用
(?x)              # allow comments and ignore whitespace
Aggregate\(
(?:
  [^()]           # anything but ( and )
| (?<open> \( )   # ( -> open++
| (?<-open> \) )  # ) -> open--
)*
(?(open) (?!) )   # fail if open > 0
\)


我不确定输入的变化程度,但问题中的字符串示例就像would work一样简单:

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

答案 2 :(得分:0)

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

Aggregate\(([^(]*\([^)]*\))*[^()]\)

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

  

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

注意那里的SUM(foo(bar), baz())

在rubular上查看live demo

答案 3 :(得分:0)

如果最终考虑避免使用正则表达式,这里是解析的替代方法,它使用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>", "]");
    }
}