复杂的正则表达式或字符串解析

本文关键字:字符串 正则表达式 复杂 | 更新日期: 2023-09-27 18:21:53

我们正在尝试使用url进行复杂的查询和过滤
我设法使用表达式树和正则表达式和字符串操作的组合来实现一些更简单的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与方括号匹配,对单个项目效果良好——当我们嵌套我正在努力的值时。

Regex看起来像

@"'((.*?)')"

我需要一些使用Regex来匹配嵌套括号的方法,如有帮助,不胜感激。

复杂的正则表达式或字符串解析

您可以将字符串转换为有效的XML(只是一些简单的替换,没有验证):

var output = filterstring
    .Replace("(","<node>")
    .Replace(")","</node>")
    .Replace("|","<andNode/>")
    .Replace("^","<orNode/>");

然后,您可以使用例如System.Xml.Linq来解析XML节点。

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>

我知道您想要在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);
}

Regex理解一个(名称:操作:值),它不关心所有其他东西。

运行此代码后,您可以获得如下值:

values["categoryid"]
values["categoryname"]
values["description"]

我希望这将帮助你的探索。

我认为你应该为此制作一个合适的解析器——它实际上会更简单、更可扩展,并在未来为你节省时间和麻烦。您可以使用任何现有的解析器生成器,如Irony或ANTLR。