正则表达式解析一个简单的odata查询

时间:2013-06-05 06:17:24

标签: .net regex

我正在尝试创建一个正则表达式来解析以下2个字符串

Country eq 'United States' and Value eq 1234.45M and CreatedOn eq '2013-06-05T06:04:23.2111146Z'
Value eq 1234.45M and Status eq 'Active' and CategoryID eq 1 and Country eq 'United States'

基本上这些是 $ filter 中指定的OData查询字符串。 请注意,这是为了提供有限的Odata支持,因此示例字符串只有 eq

这是我到目前为止所拥有的

(\w+)\seq\s\'{0,1}([0-9a-zA-Z,*=@#$&()-_+=!]*)\'{0,1}

除了当我在带引号的字符串中有空格(例如)时,这大部分都有效 “美国”(请注意美国和美国之间的空间),它只能选择'United

我尝试将\ s添加到要捕获的字符范围

(\w+)\seq\s\'{0,1}([0-9a-zA-Z,*\s=@#$&()-_+=!]*)\'{0,1}

但是由于字符串本身可以包含用于分隔名称和值的空格(值eq 1234)< - 请注意分隔当量

任何有关修复/重新创建上述正则表达式的指导都将非常受欢迎。

更新:我还需要支持其他过滤操作,例如('或','startswith','endswith','substringof')。

实施例: $ filter = 国家/地区eq'美国'和价值eq 1234.45M和substringof('Alfreds',CompanyName)eq true或startswith(CompanyName,'Alfr')和endswith(CompanyName,' Futterkiste')

4 个答案:

答案 0 :(得分:2)

您可以将其与此正则表达式匹配

(\w+)\s*eq\s*'?([^']*)'?(?=\s*and|$)

您的代码将是

var lst=Regex.Matches(input,regex)
                      .Cast<Match>()
                      .Select(x=>
                            new
                             {
                                 name=x.Groups[1].Value,
                                 value=x.Groups[2].Value
                             });

现在您可以迭代lst

foreach(var v in lst)
{
    v.name;
    v.value;
}

答案 1 :(得分:1)

尝试使用此正则表达式:

(\w+\seq\s'?[\w\s\.\:\-]+'?)(?= and |$)

查看示例here

我期待您的样本数据中出现错字:

  

国家eq'美国'和价值eq 1234.45M和CreatedOn eq   '2013-06-05T06:04:23.2111146Z'价值均衡1234.45M和状态   eq'Active'和CategoryID eq 1和Country eq'United States'

答案 2 :(得分:0)

请试试这个正则表达式:

(\w+)\seq\s\'?([^\']+)\'?

答案 3 :(得分:0)

我认为你应该分两部分做这件事(抱歉为伪代码,问题一般是在开头,我不是.net的人(但​​我在php中测试过)):

input = "Country eq 'United States' and Value eq 1234.45M and CreatedOn eq '2013-06-05T06:04:23.2111146Z'"
splitted = split ("and", input);

然后做我认为是替代的(因为捕获组):

foreach (splitted as s) {
    print (regex.replace ("#(\w+)\seq\s(.*)\s?$#", '$1 = $2', s));
}

如果php比我的伪代码更容易理解,这里是代码:

$string = "Country eq 'United States' and Value eq 1234.45M and CreatedOn eq '2013-06-05T06:04:23.2111146Z'";
$splitted = explode ('and', $string);

$regex = "#(\w+)\seq\s(.*)\s?$#";
foreach ($splitted as $s) {
    echo preg_replace ($regex, '$1 = $2<br />', $s);
}