5

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

我想选择'Aggregate('并在匹配处结束,中间的')'任何()东西都可以忽略。

例子:

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

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

字符串: Substr(Aggregate(SubQuery, SUM, ([Model].Remark) * ([Object].Shortname + 10) ), 0, 1)
应该返回: Aggregate(SubQuery, SUM, ([Model].Remark) * ([对象].Shortname + 10) )

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

4

4 回答 4

3

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

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

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

于 2013-08-07T13:17:50.580 回答
1

通过使用.NETs 平衡组,此解决方案适用于任何级别的嵌套括号:

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


我不确定输入的变化有多大,但对于问题中的字符串示例来说,这样简单就可以了:

Aggregate\(.*\)(?=,)
于 2013-08-07T15:21:29.410 回答
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>", "]");
    }
}
于 2013-08-07T13:52:36.110 回答
0

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

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

例如,它将在此处找到粗体文本:

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

注意SUM(foo(bar), baz())里面。

在 rubular 上查看现场演示。

于 2013-08-07T13:40:28.297 回答