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#。
这有点难看,但您可以使用类似的东西
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上观看现场演示。