(C#) 表达式树
需求是将一个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#) 表达式树的更多相关文章
- 再讲IQueryable<T>,揭开表达式树的神秘面纱
接上篇<先说IEnumerable,我们每天用的foreach你真的懂它吗?> 最近园子里定制自己的orm那是一个风生水起,感觉不整个自己的orm都不好意思继续混博客园了(开个玩笑).那么 ...
- [C#] C# 知识回顾 - 表达式树 Expression Trees
C# 知识回顾 - 表达式树 Expression Trees 目录 简介 Lambda 表达式创建表达式树 API 创建表达式树 解析表达式树 表达式树的永久性 编译表达式树 执行表达式树 修改表达 ...
- 轻量级表达式树解析框架Faller
有话说 之前我写了3篇关于表达式树解析的文章 干货!表达式树解析"框架"(1) 干货!表达式树解析"框架"(2) 干货!表达式树解析"框架" ...
- 用五分钟重温委托,匿名方法,Lambda,泛型委托,表达式树
这些对老一代的程序员都是老生常谈的东西,没什么新意,对新生代的程序员却充满着魅力.曾经新生代,好多都经过漫长的学习,理解,实践才能掌握委托,表达式树这些应用.今天我尝试用简单的方法叙述一下,让大家在五 ...
- LinqToDB 源码分析——处理表达式树
处理表达式树可以说是所有要实现Linq To SQL的重点,同时他也是难点.笔者看完作者在LinqToDB框架里面对于这一部分的设计之后,心里有一点不知所然.由于很多代码没有文字注解.所以笔者只能接合 ...
- LinqToDB 源码分析——生成表达式树
当我们知道了Linq查询要用到的数据库信息之后.接下就是生成对应的表达式树.在前面的章节里面笔者就已经介绍过.生成表达式树是事实离不开IQueryable<T>接口.而处理表达式树离不开I ...
- 干货!表达式树解析"框架"(1)
最新设计请移步 轻量级表达式树解析框架Faller http://www.cnblogs.com/blqw/p/Faller.html 关于我和表达式树 其实我也没有深入了解表达式树一些内在实现的原理 ...
- 干货!表达式树解析"框架"(2)
最新设计请移步 轻量级表达式树解析框架Faller http://www.cnblogs.com/blqw/p/Faller.html 为了过个好年,我还是赶快把这篇完成了吧 声明 本文内容需要有一定 ...
- 干货!表达式树解析"框架"(3)
最新设计请移步 轻量级表达式树解析框架Faller http://www.cnblogs.com/blqw/p/Faller.html 这应该是年前最后一篇了,接下来的时间就要陪陪老婆孩子了 关于表达 ...
- Lind.DDD.ExpressionExtensions动态构建表达式树,实现对数据集的权限控制
回到目录 Lind.DDD框架里提出了对数据集的控制,某些权限的用户为某些表添加某些数据集的权限,具体实现是在一张表中存储用户ID,表名,检索字段,检索值和检索操作符,然后用户登陆后,通过自己权限来构 ...
随机推荐
- document.referrer和history.go(-1)退回上一页区别
javascript:location=document.referrer;和javascript:history.go(-1);区别: 返回上一页,在PC端我们可以使用:history.go(-1) ...
- odoo 二次开发的一些原理
一:self是什么 目前新版的Odoo中使用到的self,是对 游标cr.用户ID.模型.上下文.记录集.缓存 的封装. 我们可以通过 self.XX 获取到这些封装的东西,比如:self.cr. ...
- ABP与多租户
ABP简介 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应用程 ...
- Jenkins windows部署
1.安装jenkins 进入https://jenkins.io/download/,下载windows安装包,解压后运行jenkins.msi进行安装. 配置jenkins (1)打开http:// ...
- CDH集群安装配置(四)- mysql 的安装
安装mysql,并且创建相关的表(只需要在chd1上面安装而且需要root权限)1.1 查看Centos自带mysql是否已经安装 yum list installed | grep mysql 卸载 ...
- lfs
LFS──Linux from Scratch,就是一种从网上直接下载源码,从头编译LINUX的安装方式.它不是发行版,只是一个菜谱,告诉你到哪里去买菜(下载源码),怎么把这些生东西( raw c ...
- oracle--dump 事务槽
01,创建环境 SQL> create table t3 (id int); Table created. SQL); row created. SQL); row created. SQL); ...
- Ubuntu 16.04 compare 软件安装
1软件官网 http://www.scootersoftware.com/download.php?zz=kb_linux_install 2.打开上述网址可看到安装信息 终端安装方式: wget h ...
- SqlHelper中SqlHelperParameterCache类的用法介绍
SqlHelper类中提供了三种可以用来管理SqlParameter参数的共享方法.下面来一一讲解: 1.CacheParameterSet 将SqlParameter参数数组存储到本地缓存中 2.G ...
- 【lua】LWT HttpdModule
要使用httpd模块,需要在脚本开头添加: require "httpd" httpd.pairs(apr_table) 用以遍历apr_table for key, value ...