如何实现表达式解析器的用户自定义el表达式函数

 上传我的文档
 下载
 收藏
该文档贡献者很忙,什么也没留下。
 下载此文档
正在努力加载中...
IKExpression 简易表达式解析器
下载积分:900
内容提示:IKExpression 简易表达式解析器
文档格式:PDF|
浏览次数:143|
上传日期: 01:05:15|
文档星级:
全文阅读已结束,如果下载本文需要使用
 900 积分
下载此文档
该用户还上传了这些文档
IKExpression 简易表达式解析器
官方公共微信1336人阅读
1. IK表达式介绍(IK Expression Introduction)
2. 快速入门(Quick Start)
3. 表达式公式规范(Expression Formula Specification)
4. 高级特性(Advance)
注:V2.1.2已发布,请参考
1. IK表达式介绍(IK Expression Introduction) IK Expression是一个开源的(OpenSource),可扩展的(Extensible),基于java语言开发的一个超轻量级(Super lightweight)的公式化语言解析执行工具包。 IK ExpressionV2.0不依赖于任何第三方的java库。它做为一个简单的jar,可以集成于任意的Java应用中。这包括了JavaEE应用(基于应用服务器的), Java桌面应用以及Java WebStart方式的应用。 IK Expression最初诞生的原因是为了能增强工作流引擎,如jBPM等对流程配置的灵活度。使其能在流程运行期获得同配置期一样灵活地对执行逻辑条件进行变更。经过扩展后的IK Expression还可以适用于各种常规业务系统的动态条件配置,如需要图形化配置应用的场合,或是模拟Excel电子表格的公式运算的场景。 同EL和BeanScript不同,IK Expression的设计目标是面向最终用户的,因此它被设计成语法简单(像数学算式),通俗易懂(支持中文变量及函数名)但功能有限的解析引擎。如果你需要一个功能强大的表达式引擎,也许IK Expression并不是最好的选择。 1.1 概要(OverView) IK Expression是一个采用逆波兰式算法结合指针栈优化的公式解析引擎,它由表达式编译、、表达式执行、变量容器、以及函数配置管理四部分构成。它具有以下特点:
支持基础运算符+ - & / % 逻辑运算符! && || 三元运算符?:以及特有的#集合运算。支持括号优先级,对&&,||,?:有短路优化处理。
支持函数执行,函数扩展,支持变量定义。
完整Jar包大小90K,API简单易学,超轻量级,无第三方类库依赖。
IK Expression 组件结构图
1.2 升级变更(Changes Log) Version2.0.2的变更:
修订了自定义函数返回类型为void时,表达式校验会抛出异常的BUG。对于void返回类型,IK-Expression将当作null类型进行计算。
Version2.0.1的变更:
添加了对表达式的折行书写的支持(即对表达式中出现CRLF的支持),方便于用户编写逻辑复杂的长表达式,增强表达式可阅读性。
Version2.0.0相对于V1.0的变更:
增加了&?:&三元操作符。
增强了&+&操作符,支持对null型,Date型,Boolean型的连接操作。
增加了自定义函数扩展,支持配置方式扩展函数和API编码方式扩展函数。
增加了函数别名映射功能,可配置中文函数别名。
增加了函数参数和返回值对java Object类型的支持。
优化&||&、&&&&、&?:&操作符,实现相应逻辑的短路处理。
修订了Date类型的==比较逻辑。原有逻辑判定时间差小于1秒为相等,现在更正为精确到秒。
修订了==比较逻辑对数值类型运算的bug,使其支持Integer,Float,Long,Double类型的混合比较,以及当这四种类型混合比较时,其中一个参数为null的情况。
修改了V1.0中类Variable的方法createVariable的参数。
废除了V1.0中的&:&操作符(使用&?:&三元操作符代替)
废除了V1.0中类ExpressionEvaluator的compileExpression方法。
2. 快速入门(Quick Start) 2.1 下载(Downloadables Overview) GoogleCode开源项目: GoogleCode SVN下载: 2.2 安装部署 IK Expression 的安装部署十分简单,安装包包含:
1. 使用说明文档(即本文档)
2. IKExpression2.0.jar
3. functionConfig.xml
其中,IKExpression2.0.jar部署于项目的lib目录中;functionConfig.xml(函数定义配置)文件放置在代码根目录(对于web项目,通常是WEB-INF/classes目录,同hibernate、log4j等配置文件相同)下即可。 2.3 API简易教程(API Tutorial) 代码样例HelloWorld
public&static&void&main(String[]&args){ &&
&&&&if(args.length&==&0){ &&
&&&&&&&&args&=&new&String[1]; &&
&&&&&&&&args[0]&=&"IK&Expression"; &&
&&&&String&expression&=&"/"Hello&World&/"&+&用户名"; &&
&&&&List&Variable&&variables&=&new&ArrayList&Variable&(); &&
&&&&variables.add(Variable.createVariable("用户名",&args[0])); &&
&&&&Object&result&=&ExpressionEvaluator.evaluate(expression,&variables); &&
&&&&System.out.println("Result&=&"&+&result);&&&&&&& &&
* Hello World Example
* @param args
public static void main(String[] args){
if(args.length == 0){
args = new String[1];
args[0] = "IK Expression";
//定义表达式
String expression = "/"Hello World /" + 用户名";
//给表达式中的变量 "用户名" 付上下文的值
List&Variable& variables = new ArrayList&Variable&();
variables.add(Variable.createVariable("用户名", args[0]));
//执行表达式
Object result = ExpressionEvaluator.evaluate(expression, variables);
System.out.println("Result = " + result);
执行结果: Hello World IK Expression API说明 *类org.wltea.expression.ExpressionEvaluator 方法1: public static Object evaluate(String expression, Collection&Variable& variables) 说明:传入表达式和表达式上下文的变量,执行表达式返回结果 参数1 :String expression, 要传入执行的表达式 参数2 :Collection&Variable& variables 表达式上下文的变量集合(详细请看类org.wltea.expression.datameta.Variable的说明)。 返回值:表达式执行结果,可能是以下类型的java对象中的一种: Int、Long、Float、Double、Boolean、String、Date、List、Object。 方法2: public static Object evaluate(String expression) 说明:对方法1的重载,执行简单的没有变量的表达式。请参考方法1说明. *类org.wltea.expression.datameta.Variable &&&&&& 该类是用来表示表达式的上下文变量的,上面的例子中用到了别名为&用户名&的上下文变量,这是也是表达式最有用的地方。例如,在jBPM的流程定义中,我们需要定义一个报销审批流程中,用来决定流程分支走向的表达式:&&&
(申请金额&&&10000)?&总经理审批&:&部门经理审批&&&
(申请金额 & 10000)?&总经理审批&:&部门经理审批&
这里需要定义一个别名为&申请金额&变量。变量通过evaluate(String expression, Collection&Variable& variables)方法中的variables参数传入表达式中。而Variable类型变量的构造十分的简单,它是标准的POJO。 方法1: public static Variable createVariable(String varName , Object varValue) 说明:根据参数别名和参数值,构造 Variable 实例 参数1 :String varName, 参数的别名,可以是中文别名 参数2 :Object varValue,参数的值 , 可以是下类型的java对象中的一种: Int、Long、Float、Double、Boolean、String、Date、List、Object。 返回值:org.wltea.expression.datameta.Variable类的实例 方法2:(直接使用构造函数) public Variable(String varName , DataType varDataType , Object varValue) 说明:根据指定的参数类型、参数别名和参数值,构造 Variable 实例 参数1 :String varName, 参数的别名,可以是中文别名 参数2 :DataType varDataType, 变量类型,它是 org.wltea.expression.datameta. BaseDataMeta.DataType枚举类型,包括的枚举值有:
//NULL类型 DATATYPE_NULL ,
//字符窜 DATATYPE_STRING ,
//布尔类 DATATYPE_BOOLEAN ,
//整型数 DATATYPE_INT ,
//长整型数 DATATYPE_LONG ,
//浮点数 DATATYPE_FLOAT ,
//双精度浮点 DATATYPE_DOUBLE ,
//日期时间 DATATYPE_DATE ,
//集合对象 DATATYPE_LIST,
//通用对象类型 &&&&&&& DATATYPE_OBJECT,
参数3 :Object varValue,参数的值 , 可以是下类型的java对象中的一种: Int、Long、Float、Double、Boolean、String、Date、List、Object。 返回值:org.wltea.expression.datameta.Variable类的实例 3. 表达式公式规范(Expression Formula Specification) 3.1 数据类型(Types, Values, and Variables) a) 数字型 : i. 整形 integer&& : -2321 , 34234 ii. 长整型 long&&& :L iii. 单精度浮点 float : 342.555F iv. 双精度浮点 double: 3 b) 字符型:&a-zA-Z& c) 布尔型:true、false d) 日期时间型:[] 或 [ 12:33:14] e) 扩展类型:List对象集合 (该类型不支持表达式字面定义,由操作符或函数运算结果生成) f) 通用对象:Object类型 (该类型不支持表达式字面定义,由操作符或函数运算结果生成) 3.2 运算符(Operators)
3.3 分割符(Separators)
a) 括号 "("& ")" && 标识优先级
b) 逗号&& "," && 分隔函数的参数
c) 方括号 "["& "]" && 标识日期型常量
d) 双引号 """ && 标识字符型常量
e) 美元号&& "$" && 函数标识前缀
f) 转义符&& "/" && 字符串转义,支持// , /&, /r , /n , /t
3.4 内部函数(Inner Functions) 内置函数是目前解析器已经实现的一些非常简单、实用的函数
3.5 语法约束(Lexical Structure)
变量命名遵循java变量命名规范(如,不能以数字打头,不能用系统操作符打头等)。
函数声明以&$&符号打头,自定义函数命名遵循java方法命名规范。
日期型常量使用&[]&符号界定,格式为 [yyyy-MM-dd 24h-mm-ss],不支持毫秒。
用户自定义函数别名不能重复。(详细请参阅本文4.1章节)
用户自定义函数的参数和返回值类型限定于3.1章节描述的数据类型。(详细请参阅本文4.1章节)
3.6 公式样例(Formula Example) 1. +、- 、* 、/ 、%(取模) 常规的算术运算,支持括号优先级 : 如:常见的OA中用于年休假工资计算公式 3000 / 21.5 *(12 - 转正月份)/ 2& 其中,&转正月份&可以是上下文变量 2. 不同数据类型的字符串连接 : &ABC&+(123+10) 运算结果 &ABC133& &ABC&+ 123 + 10 运算结果&ABC12310& &[] + false + 123 + /"a String/" + null& 运算结果 & 00:00:00false123a String& (PS:忽略 null型变量) 3. & &= & &= == !=逻辑比较运算,返回布尔值 :
3-1.数值大小比较 :
运算结果 true
3-2.字符大小比较 : &1234&&&223& 运算结果 fasle
3-3.日期大小比较 : [] &= [] && true
3-4.同null的 == 与 != 比较 : 申请人!=null& (其中,&申请人&为执行上下文的变量)
4. 逻辑与、逻辑或、逻辑非运算: true& &&& $DAYEQUALS([] , []) &&false true& ||& $DAYEQUALS([] , []) && true true& && !$DAYEQUALS([] , []) && true 5. 结果连接运算&#&: 1000/10& #& []&$SYSDATE()& # &ABC&+123 运算结果 包含 100 , false , &ABC123&三种不同类型对象的List 6. 函数与操作符混合、嵌套调用,如:
$DAYEQUALS( &&
&&&&$CALCDATE( &&
&&&&&&&&$SYSDATE()&,&0&,&0&,& &&
&&&&&&&&(8+11-5*(6/3))&*&(2-&59&%&7)&, &&
&&&&&&&&0&,0,0&), &&
&&&&[2009-10-01] &&
$DAYEQUALS(
$CALCDATE(
$SYSDATE() , 0 , 0 ,
(8+11-5*(6/3)) * (2- 59 % 7) ,
运算结果 false 4. 高级特性(Advance) 4.1 函数定制(Functions Customize) &&&&& IK-Expression最吸引人的特性莫过于它允许你以非常简单的方式扩展你的自定义函数。IK-Expression带有一个xml配置文件functionConfig.xml。在使用IK-Expression时,该配置文件应放置于class的根目录中(如同spring和hibernate等的配置文件一样)。配置文件内部格式如下: functionConfig.xml
&version="1.0"&encoding="UTF-8"&&
&&&&&class="org.wltea.expression.function.SystemFunctions"&&
&&&&&&&&&name="CONTAINS"&method="contains"&&
&&&&&&&&&&&&java.lang.String&&
&&&&&&&&&&&&java.lang.String&&
&&&&&&&&&&
&&&&&&&&&name="STARTSWITH"&method="startsWith"&&
&&&&&&&&&&&&java.lang.String&&
&&&&&&&&&&&&java.lang.String&&
&&&&&&&&&&
&&&&&&&&&name="ENDSWITH"&method="endsWith"&&
&&&&&&&&&&&&java.lang.String&&
&&&&&&&&&&&&java.lang.String&&
&&&&&&&&&&
&&&&&&&&&name="CALCDATE"&method="calcDate"&&
&&&&&&&&&&&&java.util.Date&&
&&&&&&&&&&&&int&&
&&&&&&&&&&&&int&&
&&&&&&&&&&&&int&&
&&&&&&&&&&&&int&&
&&&&&&&&&&&&int&&
&&&&&&&&&&&&int&&
&&&&&&&&&&
&&&&&&&&&name="SYSDATE"&method="sysDate"&&&
&&&&&&&&&name="DAYEQUALS"&method="dayEquals"&&
&&&&&&&&&&&&java.util.Date&&
&&&&&&&&&&&&java.util.Date&&
&&&&&&&&&&
&?xml version="1.0" encoding="UTF-8"?&
&function-configuration&
&!-- 系统函数默认配置 --&
&bean class="org.wltea.expression.function.SystemFunctions"&
&function name="CONTAINS" method="contains"&
&parameter-type&java.lang.String&/parameter-type&
&parameter-type&java.lang.String&/parameter-type&
&/function&
&function name="STARTSWITH" method="startsWith"&
&parameter-type&java.lang.String&/parameter-type&
&parameter-type&java.lang.String&/parameter-type&
&/function&
&function name="ENDSWITH" method="endsWith"&
&parameter-type&java.lang.String&/parameter-type&
&parameter-type&java.lang.String&/parameter-type&
&/function&
&function name="CALCDATE" method="calcDate"&
&parameter-type&java.util.Date&/parameter-type&
&parameter-type&int&/parameter-type&
&parameter-type&int&/parameter-type&
&parameter-type&int&/parameter-type&
&parameter-type&int&/parameter-type&
&parameter-type&int&/parameter-type&
&parameter-type&int&/parameter-type&
&/function&
&function name="SYSDATE" method="sysDate" /&
&function name="DAYEQUALS" method="dayEquals"&
&parameter-type&java.util.Date&/parameter-type&
&parameter-type&java.util.Date&/parameter-type&
&/function&
&!-- 用户函数配置
,请在这里定制您自己的函数--&
&/function-configuration&
配置文件中默认配置了系统内部函数定义(在没有绝对必要的原因下,不建议修改系统默认函数配置)。在默认配置的下方,用户可以定义自己的函数,格式如下: 用户自定义函数配置
&class="org.wltea.expression.test.TestFunctions"&&
&&&&&type="java.lang.Integer"123&&
&&&&&type="java.lang.String"aa&&
&name="问好"&method="sayHello"&&
&&&&java.lang.String&&
&bean class="org.wltea.expression.test.TestFunctions"&
&constructor-args&
&constructor-arg type="java.lang.Integer"&123&/constructor-arg&
&constructor-arg type="java.lang.String"&aa&/constructor-arg&
&/constructor-args&
&function name="问好" method="sayHello"&
&parameter-type&java.lang.String&/parameter-type&
&/function&
这里自定义了一个名称为&问好&的函数,它有一个String类型的参数。该函数映射对应于org.wltea.expression.test.TestFunctions类的sayHello方法,而类org.wltea.expression.test.TestFunctions具有一个构造函数,构造函数带有Integer型和String型的参数。配置中给出了构造函数的初始化参数&123&和&aa&。通过上述定义,用户就可以在表达式中使用该函数,如: && $问好(当前用户) , 其中&当前用户&为表达式的上下文变量。 上述例子直观的展示了用户函数自定义的过程。下面,我们将系统的了解一下IK-Expression的函数扩展定义规则和约束: 1. 在IK-Expression中,函数直接对应于java的一个类的一个明确的方法。如:$CONTAINS对应org.wltea.expression.function.SystemFunctions类的contains方法; 2. 所有的函数定义前,必须先定义对应的java类。如果该类使用带参数的构造函数,则必须提供明确的构造参数,如:
&class="org.wltea.expression.test.TestFunctions"&&
&&&&&&&&&type="java.lang.Integer"123&&
&&&&&&&&&type="java.lang.String"aa&&
&&&&&name="问好"&method="sayHello"&&
&&&&&java.lang.String&&
&bean class="org.wltea.expression.test.TestFunctions"&
&constructor-args&
&constructor-arg type="java.lang.Integer"&123&/constructor-arg&
&constructor-arg type="java.lang.String"&aa&/constructor-arg&
&/constructor-args&
&function name="问好" method="sayHello"&
&parameter-type&java.lang.String&/parameter-type&
&/function&
3. java类的加载和实例化在初始化阶段一次性完成。目前IK-Expression仅支持单例形式的加载,即对一个java类仅实例化一次。 4. 定义函数时,必须明确定义函数对应java方法,以及java方法的参数类型和顺序,如:
&name="CONTAINS"&method="contains"&&
&&&&java.lang.String&&
&&&&java.lang.String&&
&function name="CONTAINS" method="contains"&
&parameter-type&java.lang.String&/parameter-type&
&parameter-type&java.lang.String&/parameter-type&
&/function&
你可以使用不同的函数名(英文的和中文的),对应相同的java方法,但对java中的方法重载必须使用不同的函数名对应(即,IK-Expression不支持函数名重载) 5. 函数的参数和返回值只能是IK-Expression支持的数据类型(请参考3.1数据类型 章节). 6. 为了增加灵活性,IK-Expression给出了一个通过编码方式添加自定义函数的static方法。 函数扩展API说明 *类org.wltea.expression.function.FunctionLoader 方法1: public static void addFunction(String functionName, Object instance, Method method) 参数1 :String functionName, 要定义的函数名称(中英文皆可)。 参数2 :Object instance 函数要映射的java 类的实例。 参数3 :Method method 函数要映射的java 类的方法对象。
(全文终)
下载地址:
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:29535次
排名:千里之外
转载:11篇
(1)(2)(1)(1)(1)(1)(1)(5)(3)2017年4月 Delphi大版内专家分月排行榜第二2017年1月 Delphi大版内专家分月排行榜第二2014年10月 Delphi大版内专家分月排行榜第二2014年9月 Delphi大版内专家分月排行榜第二
本帖子已过去太久远了,不再提供回复功能。应用C语言编写ADAMS用户自定义函数的研究_纪玉杰_图文_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
应用C语言编写ADAMS用户自定义函数的研究_纪玉杰
阅读已结束,下载文档到电脑
想免费下载本文?
定制HR最喜欢的简历
你可能喜欢1859人阅读
工作点滴(37)
前段日子师兄让我整理开源的公式解析器项目,我到网上查了两天,对大部分有人维护的开源项目进行了整理和总结:现在记在此处。
开源项目名称
在运行时解析计算静态和动态表达式;支持数学,布尔,字符串,函数表达式;支持大部分的数学和布尔运算符;支持自定义函数;支持嵌套函数;支持解析;支持自定义变量解析器;
官网:http://jeval.sourceforge.net
不支持嵌套变量
处理大部分的数学公式和字符串,通过继承接口来实现个人所需的运算;支持自定义变量解析器;该项目一直在更新,最近一次更新是今年十月七号
wiki:/p/jexel/w/list
不支持变量替换
Aviator是直接将表达式编译成Java字节码,交给JVM去执行
支持大部分运算操作符,包括算术操作符、关系运算符、逻辑操作符、位运算符、正则匹配操作符(=~)、三元表达式?: ,并且支持操作符的优先级和括号强制优先级;支持函数调用和自定义函数;支持传入变量,支持类似a.b.c的嵌套变量访问;支持数组的访问;支持正则表达式;
http://www.blogjava.net/killme2008/archive//331296.html
依赖两外两个jarcommons-beanutils和commons-logging&
自定义函数及公式
不支持变量替换
数学科学计算:包括线性方程组,统计,小波,牛顿力学。
jar包太多,不支持变量替换
IKExpressoin
支持中文变量及函数名;支持基本运算;函数运算;支持自定义函数;
不支持变量嵌套
兼容 JavaScript 运算规则的简单的表达式解释引擎,可以通过Map接口,或者JavaBean给出一个变量集合,能后通过表达式从这个集合中抽取变量,再通过表达式逻辑生成你需要的数据;支持函数扩展,操作符别名定义,操作符定义
不支持变量嵌套
支持大量的数学运算;其他功能都差不多;支持变量嵌套(顺序执行)
wiki:/jep/doc/html/variables.html
基本运算;变量、函数自定义;支持变量嵌套(顺序执行)
支持中文变量;支持基本运算;函数运算;支持自定义函数;可调用java方法;
不支持变量嵌套
另附两个开源网站:
中国开源社区
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:770398次
积分:10095
积分:10095
排名:第1679名
原创:68篇
转载:1118篇
评论:82条
(1)(1)(2)(11)(14)(14)(34)(113)(127)(97)(14)(49)(95)(30)(71)(67)(7)(178)(33)(6)(6)(27)(4)(1)(7)(8)(1)(6)(57)(9)(3)(7)(1)(1)(10)(9)(7)(4)(2)(11)(1)(6)(4)(1)(1)(3)(2)(2)(14)(9)}

我要回帖

更多关于 用户自定义函数 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信