需求是将一个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. 初识express

    初识Express 1.简介: express是基于Nodejs平台的快速,开放,极简的web开发框架 2.安装 npm install express --save 3.Hello world: c ...

  2. L2-2 小字辈 (25 分)

    本题给定一个庞大家族的家谱,要请你给出最小一辈的名单. 输入格式: 输入在第一行给出家族人口总数 N(不超过 100 000 的正整数) —— 简单起见,我们把家族成员从 1 到 N 编号.随后第二行 ...

  3. redis的持久化相关操纵

    一.redis数据持久化(数据保存在硬盘上) 1. 关系型数据库Mmysql持久化 任何增删改语句都是在硬盘上操作(安全) 断电,硬盘上数据还在 2.非关系型数据库 默认所有的增删改都是在内存中操作( ...

  4. 剑指offer——面试题22:链表中倒数第k个节点

    注意代码的鲁棒性! 函数: ListNode* TheLastKthNode(ListNode* pHead,int k) { ) return nullptr; ListNode* quickNod ...

  5. springMVC的一些入门配置

    1.springMVC的描述 1.1.SpringMVC是Spring框架内置的MVC的实现.SpringMVC就是一个Spring内置的MVC子框架. 1.2.SpringMVC的作用是实现页面和后 ...

  6. SpringBoot学习(一)

    一.Spring Boot Spring是JavaEE轻量级代替品.无需开发重量级的(EJB),Spring为企业级Java开发提供了一种相对简单的方法,通过依赖注入和面向切面编程,用简单的POJO对 ...

  7. 面经问题总结——django相关

    1.让你从头设计一个web框架,第一步你会做什么? 2.django的orm是怎么实现的? 3.django的URL路径映射是怎么实现的? 4.平常你怎么运用django提供的钩子函数? 5.三级分销 ...

  8. python - 斐波那契(Fibonacci)数列

    斐波那契数列即数列中每一项等于它前面两项的和,公式如下: f(n) = f(n-1) + f(n-2)    n>2        -----        递推公式 f(n) = 1     ...

  9. easyUI----纵向合并单元格

    使用Easyui-DataGrid过程用.做统计/报表等时经常会使用到合并单元格,原生态Easyui-DataGrid没有合并单元格的属性或方法. 解决方案: 代码一 onLoadSuccess: f ...

  10. 利用C#结合net use命令破解域帐号密码

    背景 我的职业是程序猿,而所在的工作单位因各种原因,对上网帐号有严格控制,近期竟然把我们的上网帐号全部停用,作为程序猿,不能上网,就如同鱼儿没有水,煮饭没有米,必须想办法解决此问题.公司的局域网环境是 ...