前言
业务需求中遇到字符串所组成的数学表达式,替换完数据后想计算出结果;
类似于这样👇👇👇
1. (400-0)*100+(600-400)*150+(配置值-600)*PV
2. 配置值*PV*(-10) 得出计算结果
3. 配置值>2 4<配置值<10 得出布尔值
但是让Java做字符串的数学操作很麻烦,所以引入新的jar处理
有任何问题可以留言或者查看此API文档
pom
QLExpress 为阿里开源的一个动态脚本引擎解析工具
<!--https://search.maven.org/search?q=a:QLExpress-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>QLExpress</artifactId>
<version>3.2.7</version>
</dependency>
示例一 数学公式
public static void main(String[] args) throws Exception {
//创建不需要高精度 11000.0 不需要debug日志输出 高精度10999.999999999998 空参默认高精度
ExpressRunner runner = new ExpressRunner(true,false);
DefaultContext<String, Object> context = new DefaultContext<>();
String str="(400-0)*100+(600-400)*150+(配置值-600)*PV";
//注意数学运算时为数字 不是字符串 可理解为替换关键字
context.put("配置值",5);
context.put("PV",1);
Object result = runner.execute(str, context, null, true, false);
System.out.println(result);
}
注意自己替换的关键字后 式子必须为正确的可计算式子,出现未知数会报错
入参
/**
* 执行一段文本
* @param expressString 程序文本
* @param context 执行上下文,可以扩展为包含ApplicationContext
* @param errorList 输出的错误信息List
* @param isCache 是否使用Cache中的指令集,建议为true
* @param isTrace 是否输出详细的执行指令信息,建议为false
* @param aLog 输出的log
* @return
* @throws Exception
*/
示例二 布尔值
有时候表达式的结果为布尔值,类似于这样
配置值=3
配置值>4
配置值<=9
1<配置值<5
1<=配置值<=5
>15
需要知道是否符合某个指定条件
普通java语法
//支持 +,-,*,/,<,>,<=,>=,==,!=,<>【等同于!=】,%,mod【取模等同于%】,++,--,
//in【类似sql】,like【sql语法】,&&,||,!,等操作符
//支持for,break、continue、if then else 等标准的程序控制逻辑
n = 10;
sum = 0;
for(i = 0; i < n; i++) {
sum = sum + i;
}
return sum;
//逻辑三元操作
a = 1;
b = 2;
maxnum = a > b ? a : b;
这些他是支持的,But,业务中的拓展,类似于 配置值=3
或 1<配置值<5
这类替换情况,这个工具类不能处理,因为Java语言识别布尔有特定条件,正确表达为
配置值=3 ==> 配置值==3 (需要两个等于号)
1<配置值<5 ==> 1<配置值 && 配置值<5 (需要分别做判断再与操作)
>15 ==> 配置值>15(缺乏替换配置条件,必须有个关键字用来后续替换)
为了解决上述问题,我们在传参之前,需要对表达式进行处理
private String defaultValue="配置值";
private String defaultValue2="<配置值<";
private String defaultValue3="<=配置值<";
private String defaultValue4="<=配置值<=";
private String defaultValue5="<配置值<=";
public String judgeStr(String str){
//无关键字 >15
if(!str.contains(defaultValue)){
return defaultValue+str;
}
//配置值=4
if(str.contains(defaultValue+"=")){
return str.replace("=","==");
}
//1<配置值<=4
if(str.contains(defaultValue2)||str.contains(defaultValue3)||str.contains(defaultValue4)||str.contains(defaultValue5)){
return str.replace(defaultValue,defaultValue+"&&"+defaultValue);
}
System.out.println("其他表达式:"+str);
return str;
}
Object result = runner.execute(judgeStr(str), context, null, true, false);
输出为布尔值
拓展
另一个工具类也可以处理上述请求,可以尝试JEP