https://github.com/nreco/lambdaparser

https://github.com/dynamicexpresso/DynamicExpresso

https://eval-expression.net/eval-execute

### 1、Z.Expressions.Eval 表达式解析

Z.Expression.Eval是一个免费开源的（后续收费了），可扩展的，超轻量级的公式化语言解析执行工具包，可以在运行时解析C#表达式的开源免费组件。Z.Expressions从2.0开始支持了NetCore，但是收费的。参考地址：https://riptutorial.com/eval-expression/learn/100000/getting-started 或者 https://eval-expression.net/eval-execute

```//匿名类型
string expression = "a*2 + b*3 - 3";
int result = Eval.Execute<int>(expression, new { a = 10, b = 5 });
Console.WriteLine("{0} = {1}", expression, result); //a*2 + b*3 - 3 = 32```

```//指定参数
expression = "{0}*2 + {1}*3 - 3";
result = Eval.Execute<int>(expression, 10, 5);
Console.WriteLine("{0} = {1}", expression, result);//{0}*2 + {1}*3 - 3 = 32```

```//类对象
expression = "a*2 + b*3 - 3";
dynamic expandoObject = new ExpandoObject();
expandoObject.a = 10;
expandoObject.b = 5;

result = Eval.Execute<int>(expression, expandoObject);
Console.WriteLine("{0} = {1}", expression, result); //a*2 + b*3 - 3 = 32```

```//字典对象
expression = "a*2 + b*3 - 3";
var values = new Dictionary<string, object>()
{
{ "a", 10 },
{ "b", 5 }
};

result = Eval.Execute<int>(expression, values);
Console.WriteLine("{0} = {1}", expression, result);//a*2 + b*3 - 3 = 32```

```//委托类型1
expression = "{0}*2 + {1}*3";
var compiled = Eval.Compile<Func<int, int, int>>(expression);
result = compiled(10, 15);
Console.WriteLine("{0} = {1}", expression, result);//{0}*2 + {1}*3 = 65

//委托类型2
expression = "a*2 + b*3";
compiled = Eval.Compile<Func<int, int, int>>(expression, "a", "b");
result = compiled(10, 15);
Console.WriteLine("{0} = {1}", expression, result);//a*2 + b*3 = 65```

```//字符串扩展支持-匿名类型
expression = "a*2 + b*3 - 3";
result = expression.Execute<int>(new { a = 10, b = 5 });
Console.WriteLine("{0} = {1}", expression, result);//a*2 + b*3 - 3 = 32

//字符串扩展支持-字典类型
expression = "a*2 + b*3 - 3";
values = new Dictionary<string, object>()
{
{ "a", 10 },
{ "b", 5 }
};
result = expression.Execute<int>(values);
Console.WriteLine("{0} = {1}", expression, result);//a*2 + b*3 - 3 = 32```

### 2、NReco.LambdaParser 表达式解析

```/// <summary>
/// NReco.LambdaParser 表达式解析
/// </summary>
private void btnLamdaParser_Click(object sender, EventArgs e)
{
var lambdaParser = new NReco.Linq.LambdaParser();

var dict = new Dictionary<string, object>();
dict["pi"] = 3.14M;
dict["one"] = 1M;
dict["two"] = 2M;
dict["test"] = "test";
Console.WriteLine(lambdaParser.Eval("pi>one && 0<one ? (1+8)/3+1*two : 0", dict)); // --> 5
Console.WriteLine(lambdaParser.Eval("test.ToUpper()", dict)); // --> TEST

Console.WriteLine(lambdaParser.Eval("pi>one && 0<one ", dict)); // --> True
Console.WriteLine(lambdaParser.Eval("test.ToUpper()", dict)); // --> TEST
}```

```    var lambdaParser = new LambdaParser();
var evalResult = lambdaParser.Eval(repalce, dict);```

### 3、DynamicExpresso 表达式解析

```var interpreter = new Interpreter();
var result = interpreter.Eval("8 / 2 + 2");```

```var target = new Interpreter();
double result = target.Eval<double>("Math.Pow(x, y) + 5",
new Parameter("x", typeof(double), 10),
new Parameter("y", typeof(double), 2));```

```var interpreter = new Interpreter();
var parameters = new[] {
new Parameter("x", 23),
new Parameter("y", 7)
};
Assert.AreEqual(30, interpreter.Eval("x + y", parameters));```

```var target = new Interpreter().SetVariable("myVar", 23);
Assert.AreEqual(23, target.Eval("myVar"));```

```var interpreter = new Interpreter();
var dict = new Dictionary<string, object>();

foreach (var v in dict)
{
object value = v.Value;
int para = 0;
if (int.TryParse(v.Value.ToString(), out para))
{
value = (float)para;
}
interpreter.SetVariable(v.Key, value);
}
Console.WriteLine(interpreter.Eval("a+b").ToString()); //3
Console.WriteLine(interpreter.Eval("a/b").ToString()); //0.5
Console.WriteLine(interpreter.Eval("a > b").ToString()); //False
Console.WriteLine(interpreter.Eval("str == 'f'").ToString()); //True```

```    var customers = new List<Customer> {
new Customer() { Name = "David", Age = 31, Gender = 'M' },
new Customer() { Name = "Mary", Age = 29, Gender = 'F' },
new Customer() { Name = "Jack", Age = 2, Gender = 'M' },
new Customer() { Name = "Marta", Age = 1, Gender = 'F' },
new Customer() { Name = "Moses", Age = 120, Gender = 'M' },
};
string whereExpression = "customer.Age > 18 && customer.Gender == 'F'";

Func<Customer, bool> dynamicWhere = interpreter.ParseAsDelegate<Func<Customer, bool>>(whereExpression, "customer");
Console.WriteLine(customers.Where(dynamicWhere).Count());//=> 1

var customer_query = (new List<Customer> {
new Customer() { Name = "David", Age = 31, Gender = 'M' },
new Customer() { Name = "Mary", Age = 29, Gender = 'F' },
new Customer() { Name = "Jack", Age = 2, Gender = 'M' },
new Customer() { Name = "Marta", Age = 1, Gender = 'F' },
new Customer() { Name = "Moses", Age = 120, Gender = 'M' },
}).AsQueryable();
whereExpression = "customer.Age > 18 && customer.Gender == 'F'";

var expression = interpreter.ParseAsExpression<Func<Customer, bool>>(whereExpression, "customer");
Console.WriteLine(customer_query.Where(expression).Count());//=> 1```

### 4、SQL条件语句的正则表达式和字符串求值处理

```        private void btnRegexExtract_Click(object sender, EventArgs e)
{
var source = this.txtSource.Text;

//先替换部分内容 \sand|\sor
source = Regex.Replace(source, this.txtReplaceRegex.Text, "");//替换表达式
//增加一行记录主内容
this.txtContent.Text += "替换正则表达式后内容:";
this.txtContent.AppendText(Environment.NewLine);
this.txtContent.Text += source;
this.txtContent.AppendText(Environment.NewLine);

//在匹配内容处理
var regex = new Regex(this.txtRegex.Text);
var matches = regex.Matches(source);

//遍历获得每个匹配的内容
var fieldList = new List<string>();
int i = 0;
foreach (Match match in matches)
{
this.txtContent.AppendText(match.Value);
this.txtContent.AppendText(Environment.NewLine);
if (i++ % 2 == 0)
{
}
}
this.txtContent.AppendText("获得表达式键：");
this.txtContent.AppendText(Environment.NewLine);
this.txtContent.AppendText(fieldList.ToJson());
this.txtContent.AppendText(Environment.NewLine);

var repalce = ReplaceExpress(this.txtSource.Text);
this.txtContent.AppendText("替换And=>&& or=>|| '=> \" 操作符后内容:");
this.txtContent.AppendText(Environment.NewLine);
this.txtContent.AppendText(repalce);
}```
```        /// <summary>
/// 替换And=>&& or=>|| '=> \" 操作符后内容
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
private string ReplaceExpress(string source)
{
//操作符替换表达式
var repalce = Regex.Replace(source, @"\sand\s", " && "); //and => &&
repalce = Regex.Replace(repalce, @"\sor\s", " || "); //or => ||
repalce = Regex.Replace(repalce, @"'", "\""); //'=> \"

return repalce;
}```

```        private void btnRunExpression_Click(object sender, EventArgs e)
{
//操作符替换表达式
var repalce = ReplaceExpress(this.txtSource.Text);
this.txtContent.Text = "替换And=>&& or=>|| '=> \" 操作符后内容:";
this.txtContent.AppendText(Environment.NewLine);
this.txtContent.Text += repalce;
this.txtContent.AppendText(Environment.NewLine);
this.txtContent.AppendText(Environment.NewLine);

//(Amount> 500 and Title ='Leader') or Age> 32
var dict = new Dictionary<string, object>();
dict["Amount"] = 600;
dict["Age"] = 40;

this.txtContent.AppendText("字典内容");
foreach(var key in dict.Keys)
{
this.txtContent.AppendText(\$"{key}:{dict[key]} ");
}
this.txtContent.AppendText(Environment.NewLine);
this.txtContent.AppendText(Environment.NewLine);

//var valComparer = new ValueComparer() { NullComparison = ValueComparer.NullComparisonMode.Sql };
//var lambdaParser = new LambdaParser(valComparer);
var lambdaParser = new LambdaParser();
var express1 = "(Amount> 500 && Title = \"Leader\") or Age>30";
var result1 = lambdaParser.Eval(express1, dict);
this.txtContent.AppendText("LambdaParser 表达式处理：");
this.txtContent.AppendText(Environment.NewLine);
this.txtContent.AppendText(express1 + " => " + result1);

var express2 = "( Amount> 500 && Title =\"leader\" )"; //字符串比较（''=> ""）
var result2 = lambdaParser.Eval(express2, dict);
this.txtContent.AppendText(Environment.NewLine);
this.txtContent.AppendText(express2 + " => " + result2);

var express3 = "Amount> 500";
var result3 = lambdaParser.Eval(express3, dict);
this.txtContent.AppendText(Environment.NewLine);
this.txtContent.AppendText(express3 + " => " + result3);

var express4 = "Title = \"Leader\" "; //字符串比较（''=> ""）
var result4 = lambdaParser.Eval(express4, dict);
this.txtContent.AppendText(Environment.NewLine);
this.txtContent.AppendText(express4 + " => " + result4);

this.txtContent.AppendText(Environment.NewLine);

//DynamicExpresso 表达式解析处理
this.txtContent.AppendText(Environment.NewLine);
this.txtContent.AppendText(Environment.NewLine);
this.txtContent.AppendText("DynamicExpresso 表达式解析处理：");

var interpreter = new Interpreter();
foreach (var v in dict)
{
interpreter.SetVariable(v.Key, v.Value);
}
//express3 = "Amount> 500";
var result33 = interpreter.Eval(express3);
this.txtContent.AppendText(Environment.NewLine);
this.txtContent.AppendText(express3 + " => " + result33);

//使用''出错，字符串比较需要使用""
try
{
express4 = "Title == \"Leader\" ";
var result44 = interpreter.Eval(express4);
this.txtContent.AppendText(Environment.NewLine);
this.txtContent.AppendText(express4 + " => " + result44);
}
catch(Exception ex)
{
this.txtContent.AppendText(Environment.NewLine);
this.txtContent.AppendText(express4 + ",解析出错 => " + ex.Message);
}

//var dict = new Dictionary<string, object>();
//dict["Amount"] = 600;
//dict["Age"] = 40;
this.txtContent.AppendText(Environment.NewLine);
this.txtContent.AppendText(Environment.NewLine);
this.txtContent.AppendText("Z.Expressions.Eval 表达式解析：");
var result333 = express3.Execute<bool>(dict);
this.txtContent.AppendText(Environment.NewLine);
this.txtContent.AppendText(express3 + " => " + result333);

express4 = "Title == 'Leader'"; //Z.Expressions可以接受 ' 代替 "
var result444 = express4.Execute<bool>(dict);
this.txtContent.AppendText(Environment.NewLine);
this.txtContent.AppendText(express4 + " => " + result444);
}```

## 在C#开发中使用第三方组件LambdaParser、DynamicExpresso、Z.Expressions，实现动态解析/求值字符串表达式的更多相关文章

1. [转]页游开发中的 Python 组件与模式Presentation Transcript

转: 页游开发中的 Python 组件与模式Presentation Transcript 1. 页游开发中的 Python 组件与模式 赖勇浩( http://laiyonghao.com ) 20 ...

2. XCode和Cocoa在开发中使用第三方dylib示例

XCode和Cocoa在开发中使用第三方dylib示例 www.educity.cn   发布者:yukowang   来源:网络转载   发布日期:2014年06月13日      XCode和Co ...

3. vue中修改第三方组件的样式并不造成污染

vue引用了第三方组件, 需要在组件中局部修改第三方组件的样式, 而又不想去除scoped属性造成组件之间的样式污染. 此时只能通过>>>,穿透scoped. 但是,在sass中存在 ...

4. laravel中引入composer安装在vendor中的第三方组件

一.安装第三方组件 方法一:使用命令行安装第三方(已phpword为例): composer require phpoffce/phpword ^v0..* 方法二: 修改主项目composer.js ...

5. vue中修改第三方组件的样式不生效

问题 在使用element-ui时,有时候想要修改组件内的样式,但不成功,例如 <div class="test"> <el-button>按钮</e ...

6. Android应用开发中，第三方集成新浪微博（sinaWeiboSDK）的过程记录

作为一个android开发人员,不可避免的要学会使用和集成第三方API的能力 而新浪微博作为现在最主要的新闻速递媒体,使用十分普遍,并且提供了较为详细的API接入方法,故此选择集成sinaWeibiS ...

7. iPhone 和 iPad的ios 开发中 利用 WebViewJavascriptBridge组件，通过 UIWebView 对Html进行双向通讯

本文转载至 http://blog.csdn.net/remote_roamer/article/details/7261490 WebViewJavascriptBridge 项目的 官网 http ...

8. Android开发中导入第三方库所遇问题记录

1.重复循环依赖的问题 (1)需求 如下图所示: 在Android 项目中,采用模块化开发,一个是主跑application--Mudule A,另外一个是library--Library B 1)M ...

9. iOS开发中常用第三方库的使用和配置-GDataXML

这篇文章旨在给自己以后需要时能及时的查到,省得每次都去baidu. 1. xml解析库-GDataXML 参考文章:http://blog.csdn.net/tangren03/article/det ...

10. android app开发中的常用组件

1 Activity 1.1 Activity的启动 第一,android manifest中指定的主activity,点击app的icon启动进入. 第二,使用intent,在另外一个activit ...

## 随机推荐

1. SQL Server 2008 通用分页存储过程

1.alert USE [数据库名称] GO /****** Object: StoredProcedure [dbo].[dbTab_PagerHelper] Script Date: 08/22/ ...

2. Java线程：创建与启动

Java线程:创建与启动 一.定义线程   1.扩展java.lang.Thread类.   此类中有个run()方法,应该注意其用法: public void run() 如果该线程是使用独立的 R ...

3. OC面向对象特性：封装

概念性知识  1.c语言是面向过程编程:分析解决问题的步骤,实现函数,依次调用  2.oc语言是面向对象编程:分析问题的组成的对象,协调对象间的联系和通信,解决问题  3.#include和#impo ...

4. mybatis源码分析(3)——SqlSessionManager类

从上图可能看出,在 mybatis中,SqlSession的实现类有两个,其中SqlSessionManager类不但实现了SqlSession接口,同时也实现了SqlSessionFactory接口 ...

一,原理 详细原理请看这篇文章 springmvc + ajaxfileupload解决ajax不能异步上传图片的问题.java.lang.ClassCastException: org.apache ...

6. mysql循环插入数据

实验中经常会遇到需要多条数据的情况就想到了用SQL语句循环生成数据 DROP PROCEDURE if EXISTS test_insert; DELIMITER ;; CREATE PROCEDUR ...

7. vuex直接修改state 与 用dispatch／commit来修改state的差异

一. 使用vuex修改state时,有两种方式: 1.可以直接使用 this.\$store.state.变量 = xxx; 2.this.\$store.dispatch(actionType, pay ...

8. C++借助curses库实现俄罗斯方块

主要要实现如下几个功能:方块的移动控制.方块变形.判定方块是否接触边界和进行方块堆积.对方块进行消除. 1.方块的移动控制上下左右四个方向上-->变形,下-->加速下落,左-->向左 ...

9. 1、mysql初识

之前我们写代码需要存取信息时用的是文件可是用文件存取数据非常局限,今天我们将走进一个新的世界mysql 本片导航: 数据库由来 数据库概述 mysql介绍 下载安装 mysql软件基本管理 初识sql ...

10. Android深入源代码分析理解Aidl总体调用流程（雷惊风）

2017年開始上班的第一天.老不想工作了,假期感觉还没開始就已经结束了,唉,时间就是这样,新的一年開始了,尽管非常不想干正事,没办法,必须干起来.由于后边的路还非常长,距离六十岁还非常远. 刚上班也没 ...