Odata - 如何解析过滤器

时间:2017-07-05 07:31:25

标签: c# .net odata

我有Odata过滤器,它是字符串,看起来像:

string odataFilter = "name eq 20 and surname eq 50"

我需要完成的是从中获取以下字典:

dict["name"] = "20"
dict["surname"] = "50"

同样重要的是:我只想处理"和"和" eq"来自odata的关键词没别了。

有谁知道如何触摸问题?也许用正则表达式?

2 个答案:

答案 0 :(得分:1)

我会像https://dotnetfiddle.net/l1wueA一样使用Regex.Split

using System;
using System.Text.RegularExpressions;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        var dic = findAllAndEqFilter("name eq 20 and surname eq 50");

        Console.WriteLine("Test 1\r\n");
        foreach(var kpv in dic)
            Console.WriteLine(kpv.Key + "->" + kpv.Value);

        dic = findAllAndEqFilter("name eq 21 or surname eq 51");

        Console.WriteLine("\r\nTest 2\r\n");
        foreach(var kpv in dic)
            Console.WriteLine(kpv.Key + "->" + kpv.Value);

        dic = findAllAndEqFilter("name eq 22");

        Console.WriteLine("\r\nTest 3\r\n");
        foreach(var kpv in dic)
            Console.WriteLine(kpv.Key + "->" + kpv.Value);

        dic = findAllAndEqFilter("name lt 22");

        Console.WriteLine("\r\nTest 4\r\n");
        foreach(var kpv in dic)
            Console.WriteLine(kpv.Key + "->" + kpv.Value);
    }

    public static Dictionary<string, string> findAllAndEqFilter(string odataFilter)
    {
        Dictionary<string, string> ret = new Dictionary<string, string>(); 


        string[] byAnd = Regex.Split(odataFilter, "( and )");           

        string key = "";        

        foreach(var andSplit in byAnd)
            if(!Regex.IsMatch(andSplit, "( and )")) // remove the and       
            {
                string[] byEq = Regex.Split(andSplit, "( eq )");
                foreach(var eqSplit in byEq)
                    if(!Regex.IsMatch(eqSplit, "\\s")) // if there is no space, we can assume we got a eq       
                        if(key == "")
                            key = eqSplit;
                        else 
                        {
                            ret.Add(key, eqSplit);
                            key = "";
                        }

            }


        return ret;
    }
}

答案 1 :(得分:0)

几个小时后,我创建了一个符合我需求的正则表达式。它仅接受文本值作为撇号(')之间的字符串。此外,您可以在没有它们的情况下传递数值。

示例:命名eq'John'和age eq 75

正则表达式中的结果被分组,因此很容易从匹配集中获取它们。

"(?<PropertyName>\w+?)\s+(?<Operator>eq)\s+(?<Value>(['])(\\?.)*?\1|\d+(\.\d+)?(\s*|$))(?:\s*$|\s+(?:and)(\s+|$))"