确定字符串和解析参数中的规则类型

时间:2016-06-10 12:07:09

标签: c#

我有一个包含过滤规则的字符串:

String rule = "%john"

可用的规则类型是:

Equal = "value"
StartsWith = "value%"
EndsWith = "%value" 
In = "in(value1,value2,value3)"  
Range = [min;Max]  
Min = [min;]  
Max = [;Max]  

否定:之前的一个!之前。             例如:“![min,Max]”

鉴于其中一条规则如何确定规则类型(等于,范围等)并获取该规则的参数(value,min,Max等)?

我应该使用正则表达式吗?我对Regex不太熟悉。

1 个答案:

答案 0 :(得分:2)

嗯,在最简单的情况下(没有转义符号),没有奇怪的案例(例如,当[1;2]被视为“等于字符串”时[ 1; 2]'“)你可以单独使用正则表达式

  // Please notice the order! E.g. check for Equals last
  List<KeyValuePair<String, String>> rules = new List<KeyValuePair<string, string>>() {
    new KeyValuePair<String, String>("Max", @"^(?<Negation>!*)\[;(?<Value>.+?)\]$"),
    new KeyValuePair<String, String>("Min", @"^(?<Negation>!*)\[(?<Value>.+?);\]$"),
    new KeyValuePair<String, String>("Range", @"^(?<Negation>!*)\[(?<Value>.+?;.+?)\]$"),
    new KeyValuePair<String, String>("In", @"^(?<Negation>!*)in\((?<Value>.+?(,.+?)*)\)$"),
    new KeyValuePair<String, String>("StartsWith", @"^(?<Negation>!*)%(?<Value>.+?)$"),
    new KeyValuePair<String, String>("EndsWith", @"^(?<Negation>!*)(?<Value>.+?)%$"),
    new KeyValuePair<String, String>("Equals", @"^(?<Negation>!*)(?<Value>.+?)$"),
  };

  String filter = "!!in(abc,def,xy,pq)"; // double negations cancel each other

  foreach (var rule in rules) {
    Match match = Regex.Match(filter, rule.Value);

    if (match.Success) {
      String report = String.Format("RULE: \"{0}\"; Negation: \"{1}\"; Value: \"{2}\"",
        rule.Key,
        match.Groups["Negation"].Value.Length % 2 != 0,
        match.Groups["Value"].Value);

      Console.Write(report);

      break;
    }
  }

输出

  

规则:“在”;否定:“假”;价值:“abc,def,xy,pq”

为了将所有四个值分开,请使用Split

// ["abc", "def", "xy", "pq"]
String[] parts = match.Groups["Value"].Value.Split(',');

但是,如果有可能转义符号等,我建议实现解析器

编辑:通常,我们从语法开始,例如我们可能会来

  Types - int    (e.g. 123)      
          float  (e.g. -1.23e-54)
          string (e.g. abc, "123", ab%c, ab_c, ab\%c, ab\_c, 100\%, ab\"c, ab\\c, "in")  

请注意,我已将_添加到%;为了区分字符串与整数/浮点数,我引入了"(例如100是整数,"100"是字符串)。最后,我添加了\作为转义字符(例如,如果您想查找单引号,可以放\""\""

  Key words =        in
  Special symbols =  [ ] ( ) , ; % _

操作

  equals   (including wild cards)
  in       (including wild cards)
  range    (min, max, range) 
  negation (the only boolean operation)

然后您可以实现多阶段解析器

  • 标记生成器
  • Parser
  • 验证
  • 生成器

E.g。为了

  !!in (12%3, ab\%c, pq_x%)

我们可以

  Tokenization: "!", "!", "in", "(", "12%3", "ab\%c", "pq_x%", ")"
  Parsing:      "negation", 
                "negation", 
                 "in" (with three arguments: "12%3", "ab\%c", "pq_x%")
  Validating:   syntax is valid 
  Builder:      My_Field like '12%3' or 
                My_Field like '12\%3' escape '\' or
                My_Field like 'pq_x%'