当前位置: 首页 > 软件库 > 程序开发 > 常用工具包 >

QLExpress

java表达式计算
授权协议 Apache 2.0
开发语言 Java
所属分类 程序开发、 常用工具包
软件类型 开源软件
地区 国产
投 递 者 谷星文
操作系统 跨平台
开源组织 阿里巴巴
适用人群 未知
 软件概览

 @author qhlhl2010@gmail.com

 你想知道   a love b = ? 吗 ,你想随意定义自己的操作符号吗 ? 请使用 QLExpress工具包

QLExpress 是一个轻量级的类java语法规则引擎,作为一个嵌入式规则引擎在业务系统中使用。让业务规则定义简便而不失灵活。让业务人员就可以定义业务规则。支持标准的JAVA语法,还可以支持自定义操作符号、操作符号重载、 函数定义、宏定义、数据延迟加载等。 

这个表达式相对别的计算工具,优点主要体现在:
      A、不需要预先加载可能需要的所有属性值
      B、 用户可以根据业务需要自定义操作符号和函数
      C、可以同步输出判断错误信息,有利于提高业务系统在规则判断等使用场景下的用户体验。减少业务系统相关的处理代码。
    
       主要用途:一些业务规则的组合判断,同时需要输出相关的错误信息
  
   执行的流程:
   1、单词分解
   2、语法分析
 
  最简单Hello范例:
 
   String express = "10 * 10 + 1 + 2 * 3 + 5 * 2";
   ExpressRunner runner = new ExpressRunner();
   Object result = runner.execute(express, null, false, null);
   System.out.println("表达式计算:" + express + " = " + result);
 
  其它范例:
   ExpressRunner runner = new ExpressRunner();
  runner.addOperator("love", new LoveOperator("love"));
  runner.addOperatorWithAlias("属于", "in", "用户$1不在允许的范围");
  runner.addOperatorWithAlias("myand", "and", "用户$1不在允许的范围");
  runner.addFunction("累加", new GroupOperator("累加"));
  runner.addFunction("group", new GroupOperator("group"));
  runner.addFunctionOfClassMethod("isVIP", BeanExample.class.getName(),
    "isVIP", new String[] { "String" }, "$1不是VIP用户");
  runner.addFunctionOfClassMethod("取绝对值", Math.class.getName(), "abs",
    new String[] { "double" }, null);
  runner.addFunctionOfClassMethod("转换为大写", BeanExample.class.getName(),
    "upper", new String[] { "String" }, null); 

      在这个计算引擎里面, 执行下述表达式结果:
       Example 0 : System.out.println("ss") =  null
       Example 1 : unionName = new com.ql.util.express.test.BeanExample("张三").unionName("李四") =  张三-李四
       Example 2 : group(2,3,4) =  9
       Example 3 : 取绝对值(-5.0) =  5.0
       Example 4 : max(2,3,4,10) =  10
       Example 5 :  max(3,2) + 转换为大写("abc") =  3ABC
       Example 6 :  c = 1000 + 2000 =  3000
       Example 7 : b = 累加(1,2,3)+累加(4,5,6) =  21
       Example 8 : 三星卖家 and 消保用户  =  true
       Example 9 : 'a' love 'b' love 'c' love 'd' =  d{c{b{a}b}c}d
       Example 10 :  10 * 10 + 1 + 2 * 3 + 5 * 2 =  117
       Example 11 :  ( (1+1) 属于 (4,3,5)) and isVIP("玄难") =  false
         系统输出的错误提示信息:[用户 2 不在允许的范围,  玄难 不是VIP用户]
      
 
  表达式支持概述:
  1、基本的java语法:
    A、四则运算 : 10 * 10 + 1 + 2 * 3 + 5 * 2
   B、boolean运算: 3 > 2 and 2 > 3
     C、创建对象,对象方法调用,静态方法调用:new com.ql.util.express.test.BeanExample("张三").unionName("李四")
     D、变量赋值:a = 3 + 5
     F、支持 in,max,min:  (a in (1,2,4)) and (b in("abc","bcd","efg"))
  2、提供表达式上下文,属性的值不需要在初始的时候全部加入,
     而是在表达式计算的时候,需要什么信息才通过上下文接口获取
     避免因为不知道计算的需求,而在上下文中把可能需要的数据都加入。
     runner.execute("三星卖家 and 消保用户",errorList,true,expressContext)
     "三星卖家"和"消保用户"的属性是在需要的时候通过接口去获取。
  3、可以将计算结果直接存储到上下文中供后续业务使用。例如:
        runner.execute("c = 1000 + 2000",errorList,true,expressContext);
        则在expressContext中会增加一个属性c=3000,也可以在expressContext实现直接的数据库操作等。
  4、 可以将类和Spring对象的方法映射为表达式计算中的别名,方便其他业务人员的立即和配置。例如:
     将 Math.abs() 映射为 "取绝对值"。 则  "取绝对值(-5.0)" = "5.0"
     runner.addFunctionOfClassMethod("取绝对值", Math.class.getName(), "abs",new String[] { "double" }, null);
  5、可以为已经存在的boolean运算操作符号设置别名,增加错误信息同步输出,在计算结果为false的时候,同时返回错误信息。例如:
     runner.addOperatorWithAlias("属于", "in", "用户$1不在允许的范围")。
     用户自定义的函数同样也可以设置错误信息:例如:
   runner.addFunctionOfClassMethod("isOk", BeanExample.class.getName(),"isOk", new String[] { "String" }, "$1 不是VIP用户");
 
     则在调用List errorList = new ArrayList();
     Object result =runner.execute("( (1+1) 属于 (4,3,5)) and isOk("玄难")",errorList,true,null);
      执行结果 result = false.同时在errorList中还会返回2个错误原因:
       1、"用户 2 不在允许的范围",2、玄难 不是VIP用户  
     这在业务系统需要进行规则计算,同时需要返回
   
  6、可以自定义计算函数。例如:
     自定一个操作函数 group:
 class GroupOperator extends Operator {
 public GroupOperator(String aName) {
  this.name= aName;
 }
 public Object executeInner(Object[] list)throws Exception {
  Object result = new Integer(0);
  for (int i = 0; i < list.length; i++) {
   result = OperatorOfNumber.Add.execute(result, list[i]);
  }
  return result;
 }
 }
          然后增加到运算引擎:
     runner.addFunction("累加", new GroupOperator("累加"));
  runner.addFunction("group", new GroupOperator("group"));
          则 执行:group(2,3,4)  = 9 ,累加(1,2,3)+累加(4,5,6)=21
  7、可以自定义新的操作符号  。自定义的操作符号优先级设置为最高。例如 :
    自定一个操作函数 love:
class LoveOperator extends Operator { 
 public LoveOperator(String aName) {
  this.name= aName;
 }
 public Object executeInner(Object[] list)
   throws Exception {
  String op1 = list[0].toString();
  String op2 = list[1].toString();
  String result = op2 +"{" + op1 + "}" + op2;  
  return result;
 }
}
         然后增加到运算引擎:
      runner.addOperator("love", new LoveOperator("love"));
        则 执行:'a' love 'b' love 'c' love 'd' = "d{c{b{a}b}c}d"
  8、运算引擎在没有预编译的情况下, 执行10万次  "10 * 10 + 1 + 2 * 3 + 5 * 2" 耗时:3.187秒
             runner.execute("10 * 10 + 1 + 2 * 3 + 5 * 2", null, false,null);
            在打开 预编译缓存开关的情况下, 执行10万次 "10 * 10 + 1 + 2 * 3 + 5 * 2" 耗时:  0.171秒
             runner.execute("10 * 10 + 1 + 2 * 3 + 5 * 2", null, true,null);      
            运行引擎是线程安全的。在业务系统中实际使用过程中应该打开缓存预编译的开关,性能会更加。
             可以调用clearExpressCache()清除缓存 。
           在开启开关的情况下,会缓存解析后的最后执行指令如下所示,
           避免了字符串解析、词法分析、语法分析等步骤,简单对比一下,会提高30倍的速度:
 1:LoadData 10
  2:LoadData 10
  3:OP : * OPNUMBER[2]
  4:LoadData 1
  5:OP : + OPNUMBER[2]
  6:LoadData 2
  7:LoadData 3
  8:OP : * OPNUMBER[2]
  9:OP : + OPNUMBER[2]
  10:LoadData 5
  11:LoadData 2
  12:OP : * OPNUMBER[2]
  13:OP : + OPNUMBER[2]    
   9、这个表达式相对别的计算工具,有点主要体现在:
      A、不需要预先加载可能需要的所有属性值
      B、 用户可以根据业务需要自定义操作符号和函数
      C、可以同步输出判断错误信息,有利于提高业务系统在规则判断等使用场景下的用户体验。减少业务系统相关的处理代码。
   10、后续可以进一步优化的地方:
      A、现有的单词拆解、词法分析、语法分析都是自己写的山寨版,可以利用其他成熟的开源工具。
      B、优化具体的操作指令,提高单个操作符号的运行效率
      C、经过简单的扩展支持自定义代码片段的运行。   

  • JAVA后端开发知识总结(持续更新…) QLExpress 一、概述   由阿里的电商业务规则、表达式(布尔组合)、特殊数学公式计算(高精度)、语法分析、脚本二次定制等强需求而设计的一门动态脚本引擎解析工具。 它是线程安全的,引擎运算过程中产生的临时变量都是ThreadLocal类型。 二、语法 2.1 操作符 操作符和运算符 支持 +、-、*、/、<、>、<=、>=、==、!=、<>、%、mod

  • 1.引入依赖 <dependency> <groupId>com.alibaba</groupId> <artifactId>QLExpress</artifactId> <version>3.2.0</version> </dependency> 2.简单demo计算: (例一) public static void main(String[] args) throws

  • Drools 和 QLExpress 是两个不同的规则引擎。 Drools 是一个功能强大的商业规则引擎,可以帮助用户创建、维护和执行业务规则。它提供了多种工具来帮助用户管理规则,包括用于规则编写和测试的 Eclipse 插件,以及用于管理规则的规则引擎服务器。Drools 还支持多种语言来编写规则,包括 DRL (Drools Rule Language)、Java 和 MVEL (MVEL E

  • QLExpress操作符底层实现原理 1.OperatorAdd 代码如下: public class OperatorAdd extends Operator { public OperatorAdd(String name) { this.name = name; } public OperatorAdd(String aliasName, Strin

  • QLExpress的使用 最近公司要统计一些数据,需要定义一些统计数据的计算公式,然后通过计算公式统计数据。于是我去找了找有没有什么好用的工具。说实话,现在做开发,网上能找到许多实用的工具,而且还是开源的,非常感谢大佬们的分享。今天要说的是QLExpress。 QLExpress的简单介绍 ​ QLExpress由阿里的电商业务规则、表达式(布尔组合)、特殊数学公式计算(高精度)、语法分析、脚本二

  • 目录 QLExpress支持哪些操作符? 手机号前缀规则 demo 地址规则 demo 地址+手机号前缀组合demo 自定义操作符 自定义的对象(例如Spring对象)方法转换为表达式 QLExpress设置成单例(关键) QLExpress支持哪些操作符? //参考com.ql.util.express.instruction.op.OperatorFactory public Opera

  • QLExpress 规则引擎使用介绍 一个轻量级的类java语法规则引擎,作为一个嵌入式规则引擎在业务系统中使用。让业务规则定义简便而不失灵活。让业务人员就可以定义业务规则。支持标准的JAVA语法,还可以支持自定义操作符号、操作符号重载、函数定义、宏定义、数据延迟加载等 QLExpress的特性 1、编译执行: 编译生成基础指令后执行,性能能得到基本保障。执行过程:单词分解–>单词类型分析–>语法

  • QLExpress操作符底层实现原理(三) 1.OperatorNew 代码如下: public class OperatorNew extends OperatorBase { public OperatorNew(String name) { this.name = name; } @Override public OperateData ex

  • QLExpress操作符底层实现原理(二) 1.OperatorEqualsLessMore 代码如下: public class OperatorEqualsLessMore extends Operator { public OperatorEqualsLessMore(String name) { this.name = name; } public

  • 一. 主要流程分析 1:整体处理被 ExpressRunner 托管,可以在这个类里开启一些运行时辅助功能,比如 是否使用Cache中的指令集、是否输出详细的执行指令信息 等等,。 首先调用这个方法 ExpressRunner#execute(Sting,IExpressContext):Object ,第一个参数是表达式,第二个是上下文。 2:然后调用 ExpressRunner#parseIn

  • QLExpress相关文档可以参考:文档连接 由于网上资料很少,都是demo相互照搬。没有我想要的需求demo,所以看文档写了QLExpress对集合进行并集,交集等操作的demo,抛砖引玉,仅供参考。 import cn.hutool.json.JSONUtil; import com.ql.util.express.DefaultContext; import com.ql.util.expr

  • QLExpress:GitHub - alibaba/QLExpress: QLExpress is a powerful, lightweight, dynamic language for the Java platform aimed at improving developers’ productivity in different business scenes. public stat

  • 规则引擎定义 根据数据来匹配对应的条件,并执行规则匹配后的动作系统。如果满足某些条件,就执行相关动作。 好处 可以帮助我们把多变的业务决策部分同其他业务逻辑隔离开,是的业务人员能够自行定制业务逻辑,无需开发人员介入。常用的有Drools,uRule,QLExpress,uniRule QLExpress java语言实现,不依赖任何外部脚本引擎解析 支持宏定义、支持扩展点、轻量级、高性能和可靠性

 相关资料
  • 使用DevTools控制台的求值计算功能,探测页面上任何项的状态。 DevTools控制台允许您以特别的方式了解页面中项的状态。他可以计算JavaScript的任何表达式,控制台本身支持几个功能。 TL;DR 计算键入的表达式。 使用其中一个快捷方式选择元素。 使用 inspect()检查DOM元素和JavaScript对象。 使用$0 - 4访问最近选择的元素和对象。 操作表达式 在控制台中输入

  • 主要内容:示例在MS Access中,表达式就像Excel中的公式。 这包括一些可以单独使用或组合使用以产生结果的元素。 表达式可以包括运算符,常量,函数和标识符。 表达式可用于执行各种任务,从检索控件的值或将查询条件提供给查询来创建计算的控件和字段,或者为报表定义组级别。 在本章中,我们将着重于创建一个称为计算表达式的非常具体的表达式。创建几个计算的字段,这些字段将计算并显示不存储在数据库本身任何位置的数据,

  • 当我们想临时修攺某个变量的值或查看其内部方法返回值的时候,可以使用计算表达式功能. Android Studio中提供了一个计算表达式和代码片段的功能, 使用起来非常方便.它除了支持正则表达式计算以外,还支持操作表达式,匿名表达式和内部类的计算. 两种计算模式: Expression Mode: 计算单行表达式 Code Fragment Mode: 计算代码片段, 我们可以对声明、赋值、循环和i

  • Evaluates simple math expression like 2*4 or 10/2 and outputs its result. You can use \ operator which is equivalent to round(a/b). 计算简单的数学表达式,比如2*4 或 10/2,并输出结果。\ 操作符结果同 round(a/b)。 Very useful in CS

  • 这是一个理论上的问题: 我必须计算一个表达式,我已经从中缀转换到后缀。后缀保存在中,因为我希望避免使用。这样我就知道数字之间的除法在哪里,我可以按“正确”的顺序访问它。 它看起来是这样的: 现在我想用两个堆栈: null 如果我到达一个运算符,并且数量计数至少为2,我将执行该操作并将其推到目标堆栈上。到达原始堆栈的末尾(现在是空的),我会把所有的东西都传递给它,然后从头开始,直到只剩下结果。 我现

  • 8 表达式计算/求值 在计算表达式时,ffmpeg通过libavutil/eval.h接口调用内部计算器进行计算。 表达式可以包含一元运算符、运算符、常数和函数 两个表达式expr1和expr2可以组合起来成为”expr1;expr2” ,两个表达式都会被计算,但是新表达式(组合起来的)值实为表达式expr2的值。 表达式支持的二元运算符有:+,-,*,/,^ 一元运算符:+,- 以及下面的函数:

  • 我们正在使用iReport 5.0.1,并且已经成功地转换了我们的许多水晶报告包。 我正在处理整数和双精度数据类型的混合数据,并且我正在详细信息部分的变量字段中执行计算。 然后,我有3个变量对详细数据求和。第一个变量是上面的细节变量的直接和。第二个根据IF..THEN.ELSE语句添加一个参数或第二个参数,第三个根据类似的IF..THEN.ELSE语句减去相同的参数值。 我需要舍入组页脚中的3个变

  • 本文向大家介绍MongoDB 中聚合统计计算--$SUM表达式,包括了MongoDB 中聚合统计计算--$SUM表达式的使用技巧和注意事项,需要的朋友参考一下 我们一般通过表达式$sum来计算总和。因为MongoDB的文档有数组字段,所以可以简单的将计算总和分成两种: 1,统计符合条件的所有文档的某个字段的总和; 2,统计每个文档的数组字段里面的各个数据值的和。这两种情况都可以通过$sum表达式来