Reputation: 4054
I have Odata filter which is string and looks like that:
string odataFilter = "name eq 20 and surname eq 50"
What I need to accomplish is to get following dictionary from it:
dict["name"] = "20"
dict["surname"] = "50"
What is also important: I want to handle only "and" and "eq" keywords from odata. Nothing else.
Does anyone have an idea how to touch the problem? Maybe by regular expressions?
Upvotes: 0
Views: 1933
Reputation: 4054
After few hours I created a regex which fits my needs very well. It accepts text values only as a string between apostrophes ('). In addition you can pass number value without them.
Example: name eq 'John' and age eq 75
Results in regex are grouped so it easily to get them from matches collection.
"(?<PropertyName>\w+?)\s+(?<Operator>eq)\s+(?<Value>(['])(\\?.)*?\1|\d+(\.\d+)?(\s*|$))(?:\s*$|\s+(?:and)(\s+|$))"
Upvotes: 1
Reputation: 716
I would use Regex.Split
like this : https://dotnetfiddle.net/l1wueA
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;
}
}
Upvotes: 2