我们正在尝试使用网址进行复杂的查询和过滤 我设法让一些更简单的parst工作使用表达式树和混合使用正则表达式和字符串操作,但后来我们看了一个更复杂的字符串示例
var filterstring="(|(^(categoryid:eq:1,2,3,4)(categoryname:eq:condiments))(description:lk:”*and*”))";
我希望能够将其解析为部分,但也允许它是递归的..我想得到外观看起来像:
item[0] (^(categoryid:eq:1,2,3,4)(categoryname:eq:condiments)
item[1] description:lk:”*and*”
从那里我可以删除项目[0]部分以获得
categoryid:eq:1,2,3,4
categoryname:eq:condiments
我正在使用RegEx和字符串来查找| ^为了知道它是一个AND还是一个OR,RegEx与括号匹配,并且当我们嵌套我正在努力的值时,它就适用于单个项目。
正则表达式看起来像
@"\((.*?)\)"
我需要一些使用正则表达式匹配嵌套括号的方法,我们将不胜感激。
答案 0 :(得分:2)
您可以将字符串转换为有效的XML(只是一些简单的替换,无需验证):
var output = filterstring
.Replace("(","<node>")
.Replace(")","</node>")
.Replace("|","<andNode/>")
.Replace("^","<orNode/>");
然后,您可以使用例如System.Xml.Linq
。
XDocument doc = XDocument.Parse(output);
根据您的评论,以下是重新排列XML以获得所需包装的方式:
foreach (var item in doc.Root.Descendants())
{
if (item.Name == "orNode" || item.Name == "andNode")
{
item.ElementsAfterSelf()
.ToList()
.ForEach(x =>
{
x.Remove();
item.Add(x);
});
}
}
以下是生成的XML内容:
<node>
<andNode>
<node>
<orNode>
<node>categoryid:eq:1,2,3,4</node>
<node>categoryname:eq:condiments</node>
</orNode>
</node>
<node>description:lk:”*and*”</node>
</andNode>
</node>
答案 1 :(得分:1)
我知道您需要在filterstring中指定的值。
我的解决方案是这样的:
NameValueCollection values = new NameValueCollection();
foreach(Match pair in Regex.Matches(@"\((?<name>\w+):(?<operation>\w+):(?<value>[^)]*)\)"))
{
if (pair.Groups["operation"].Value == "eq")
values.Add(pair.Groups["name"].Value, pair.Groups["value"].Value);
}
正则表达式理解a(名称:操作:值),它并不关心所有其他东西。
运行此代码后,您可以获得如下值:
values["categoryid"]
values["categoryname"]
values["description"]
我希望这能帮助你完成任务。
答案 2 :(得分:0)