我想选择一个字符串的一部分,但问题是我想要选择的最后一个字符可能有多次出现。
我想选择'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#。
答案 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>", "]");
}
}