我有一个包含过滤规则的字符串:
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不太熟悉。
答案 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)
然后您可以实现多阶段解析器:
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%'