需求是将一个string 表达式 转换成 逻辑 表达式 并得到结果。

例如: bool result = (key1==val1) || (key2!=val2) && (key3==val3). 其中 keyN, valN 均为变量。

基本的思路是先做Express string 验证,然后进行解析。

验证可以用正则表达式。

解析最基本的方法是用 表达式树 (Express Tree).  PostFix.

C# linq 提供了一个解决方案就是 Linq 语法树。

https://www.codeproject.com/Articles/74018/How-to-Parse-and-Convert-a-Delegate-into-an-Expre

目前较好的方法是用Microsoft 的  Dynamic Linq (http://msdn.microsoft.com/en-us/vcsharp/bb894665.aspx)

static void Main(string[] args)
{
string[] exps = new string[]
{
@" ""keyA"" !=""valA"" ",
@"keyA !=""valA""",
@"(keyA ==""valA"")",
@"keyA ==""val1"" || key2 ==""val2""",
@"key1 ==""val1"" && key2 ==""val2""",
@" key1 !=""val1"" || key2 ==""val2""&& key3 != ""val3""",
@"(key1 ==""val1"" || key2 ==""val2"")&& key3 != ""val3""",
}; string pattern = @"(?<key>[\w\d_]+)""*\s*(?<equality>==|!=)\s*""*(?<value>[\w\d_]+)"; foreach (var exp in exps)
{
// Parses to get the parameters.
string formattedExp = exp;
var matches = Regex.Matches(exp, pattern);
ParameterExpression[] parameters = new ParameterExpression[matches.Count];
for (int i =; i < matches.Count; i++)
{
Debug.Write(" key[" + matches[i].Groups["key"].Value);
Debug.Write("] equality[" + matches[i].Groups["equality"].Value);
Debug.Write("] value[" + matches[i].Groups["value"].Value +"]\t\n"); parameters[i] = Expression.Parameter(typeof(string), matches[i].Groups["key"].Value); // Removing " if it has in keys.
if (exp.Contains(string.Format(@"""{0}""", matches[i].Groups["key"].Value)))
{
formattedExp = exp.Replace(string.Format(@"""{0}""", matches[i].Groups["key"].Value), matches[i].Groups["key"].Value);
}
} var e = System.Linq.Dynamic.DynamicExpression.ParseLambda(parameters, null, formattedExp); string[] GotValues = new string[matches.Count];
if (GotValues.Length == )
{
GotValues[] = "val1";
GotValues[] = "val2";
} if (GotValues.Length == )
{
GotValues[] = "val1";
GotValues[] = "val2";
GotValues[] = "val3";
} var result = e.Compile().DynamicInvoke(GotValues); Debug.WriteLine("{0} ---> {1}", e.ToString(), result);
}
}

输出如下:

keyA => (keyA != "valA") ---> True
 key[keyA] equality[!=] value[valA] 
keyA => (keyA != "valA") ---> True
 key[keyA] equality[==] value[valA] 
keyA => (keyA == "valA") ---> False
 key[keyA] equality[==] value[val1] 
 key[key2] equality[==] value[val2] 
(keyA, key2) => ((keyA == "val1") OrElse (key2 == "val2")) ---> True
 key[key1] equality[==] value[val1] 
 key[key2] equality[==] value[val2] 
(key1, key2) => ((key1 == "val1") AndAlso (key2 == "val2")) ---> True
 key[key1] equality[!=] value[val1] 
 key[key2] equality[==] value[val2] 
 key[key3] equality[!=] value[val3] 
(key1, key2, key3) => ((key1 != "val1") OrElse ((key2 == "val2") AndAlso (key3 != "val3"))) ---> False
 key[key1] equality[==] value[val1] 
 key[key2] equality[==] value[val2] 
 key[key3] equality[!=] value[val3] 
(key1, key2, key3) => (((key1 == "val1") OrElse (key2 == "val2")) AndAlso (key3 != "val3")) ---> False

参考:

https://stackoverflow.com/questions/821365/how-to-convert-a-string-to-its-equivalent-linq-expression-tree

(C#) 表达式树的更多相关文章

  1. 再讲IQueryable<T>,揭开表达式树的神秘面纱

    接上篇<先说IEnumerable,我们每天用的foreach你真的懂它吗?> 最近园子里定制自己的orm那是一个风生水起,感觉不整个自己的orm都不好意思继续混博客园了(开个玩笑).那么 ...

  2. [C#] C# 知识回顾 - 表达式树 Expression Trees

    C# 知识回顾 - 表达式树 Expression Trees 目录 简介 Lambda 表达式创建表达式树 API 创建表达式树 解析表达式树 表达式树的永久性 编译表达式树 执行表达式树 修改表达 ...

  3. 轻量级表达式树解析框架Faller

    有话说 之前我写了3篇关于表达式树解析的文章 干货!表达式树解析"框架"(1) 干货!表达式树解析"框架"(2) 干货!表达式树解析"框架" ...

  4. 用五分钟重温委托,匿名方法,Lambda,泛型委托,表达式树

    这些对老一代的程序员都是老生常谈的东西,没什么新意,对新生代的程序员却充满着魅力.曾经新生代,好多都经过漫长的学习,理解,实践才能掌握委托,表达式树这些应用.今天我尝试用简单的方法叙述一下,让大家在五 ...

  5. LinqToDB 源码分析——处理表达式树

    处理表达式树可以说是所有要实现Linq To SQL的重点,同时他也是难点.笔者看完作者在LinqToDB框架里面对于这一部分的设计之后,心里有一点不知所然.由于很多代码没有文字注解.所以笔者只能接合 ...

  6. LinqToDB 源码分析——生成表达式树

    当我们知道了Linq查询要用到的数据库信息之后.接下就是生成对应的表达式树.在前面的章节里面笔者就已经介绍过.生成表达式树是事实离不开IQueryable<T>接口.而处理表达式树离不开I ...

  7. 干货!表达式树解析"框架"(1)

    最新设计请移步 轻量级表达式树解析框架Faller http://www.cnblogs.com/blqw/p/Faller.html 关于我和表达式树 其实我也没有深入了解表达式树一些内在实现的原理 ...

  8. 干货!表达式树解析"框架"(2)

    最新设计请移步 轻量级表达式树解析框架Faller http://www.cnblogs.com/blqw/p/Faller.html 为了过个好年,我还是赶快把这篇完成了吧 声明 本文内容需要有一定 ...

  9. 干货!表达式树解析"框架"(3)

    最新设计请移步 轻量级表达式树解析框架Faller http://www.cnblogs.com/blqw/p/Faller.html 这应该是年前最后一篇了,接下来的时间就要陪陪老婆孩子了 关于表达 ...

  10. Lind.DDD.ExpressionExtensions动态构建表达式树,实现对数据集的权限控制

    回到目录 Lind.DDD框架里提出了对数据集的控制,某些权限的用户为某些表添加某些数据集的权限,具体实现是在一张表中存储用户ID,表名,检索字段,检索值和检索操作符,然后用户登陆后,通过自己权限来构 ...

随机推荐

  1. python全栈开发_day7_字符编码,以及文件的基本读取

    一:字符编码 1)什么是字符编码 将人能识别的字符等高级标识符与计算机所能识别的二进制01进行转化,这之间的交流需要一个媒介,进行两种标识符之间的转化. 字节的存储方式为八个二进制位 2)乱码 存放数 ...

  2. Angular material mat-icon 资源参考_Social

    ul,li>ol { margin-bottom: 0 } dt { font-weight: 700 } dd { margin: 0 1.5em 1.5em } img { height: ...

  3. 用servlet进行用户名和密码校验01

    用servlet进行用户名和密码校验01 编写一个servlet进行用户名和密码校验,获取登录页面的用户名密码,并显示出来 1.工作目录结构 2.首先是一个login.html,包含非常简单的登录表单 ...

  4. golang笔记

    ----------- golang打包和部署到centos7. 参考:https://blog.csdn.net/qq_33230584/article/details/81536572

  5. myEclipse卡顿解决

    1 .关闭MyEclipse的自动validation windows > perferences > myeclipse > validation 将Build下全部勾取消 如果你 ...

  6. php codeception

    前言 本测试用例只针对yii2 basic框架而写,若要支持其他框架,请自行查看phpcodeception指导(需要FQ)http://codeception.com/ yii2 basic默认已经 ...

  7. thymeleaf常用语法

    常用标签语法:①th:text<span th:text="${name}">1</span>注释:如果${name}有值则将替换掉1的值,若无则为1 ②t ...

  8. kafka集群安装及简单使用

    关于kafka是什么及原理,请参考kafka官方文档的介绍:http://kafka.apache.org/documentation/#introduction ,英文不好的同学可以看这里http: ...

  9. Case When ELSE END语句

    一.简介.Case  When   ELSE   END共有两种用法: 说实话,这种就是数据库版的switch语句,但是只是形式上很像,实际上还是有差别的!!! Create Table Test6( ...

  10. sencha touch extend 单继承 和 mixins 实现多继承

    继承可以达到代码的复用,利于维护和扩展. sencha touch 中可以通过 extend 实现单继承,通过 mixins 实现多继承. mixins 也很像实现接口,不过这些接口的方法已经实现了, ...