java通过正则进行语法分析实现表达式的逻辑判断和复杂计算实现
首先功能展示:

相关功能实现,实现功能类似js,弱语言类型:
1、核销语法解析使用正则校验和匹配实现处理,每一行是一个完整表达式
2、有系统变量使用,内置的变量可直接获取值进行相关逻辑和条件计算
3、有内容函数可供实现,具体函数可看枚举FuncEnum的定义和说明,如要扩展跟多函数,可再functionCalculateFactory中实现逻辑
4、可以通过如果...则,否则如果...则,否则,如果完完成逻辑控制
5、可以通过加(+)、减(-)、乘(*)、除(/)、求余(%)实现表达式计算
6、采用变量池存储所有自定义变量和产生的临时变量
/**
* 变量池,用于存储当前自定义变量和数据
*/
protected HashMap<String, VariateDto> VARIABLE_POOL = new HashMap<>();
7、执行过程会打印所有执行的详细步骤
8、前端编写语法高亮使用codemirror的插件改写,具体文件可看github里,使用方式如下:
// 1、定义
<textarea ref="formula-mirror-code" name="code"></textarea>
// 2、引用控件
require('../../components/qd-project/codemirror/codemirror.css');
import CodeMirror from '../../components/qd-project/codemirror/codemirror.js';
// 使用
this.$nextTick(function () {
var te = this.$refs["formula-mirror-code"]; // document.getElementById("formula-mirror-code");
this.editor = CodeMirror.fromTextArea(te, {
mode: "lu-code",
lineNumbers: true,
lineWrapping: false, // 自动换行
//extraKeys: {"Ctrl-Q": function(cm){ cm.foldCode(cm.getCursor()); }},
foldGutter: true,
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
});
//editor.foldCode(CodeMirror.Pos(13, 0));
this.editor.setValue(this.content || '');
this.editor.setSize('100%', '400px')
this.editor.on('change', ()=>{
this.$emit('input', this.editor.getValue());
this.$emit('change', this.editor.getValue());
// 直接修改pop里的属性会被视作反模式操作,会出现警告
// 由于在新的渲染机制中,每当父组件重新渲染时,子组件都会被覆盖,所以应该把props看做是不可变对象
// 应该这个组件提交个事件给父组件
//this.value = this.editor.getValue();
})
if (this.editor.getValue().length <= 0) {
this.editor.setValue("数值 分摊比例\n"
+ "数值 分摊单价\n"
+ "\n"
+ "分摊单价 = 公区表_单价\n"
+ "// 条件判断户数大于10\n"
+ "如果 分摊户数<=10 则\n"
+ " 分摊用量 = 公区表_合计用量/分摊户数*0.8\n"
+ "否则如果 分摊户数>10 && 分摊户数<20 则\n"
+ " 分摊用量 = 公区表_合计用量 /分摊户数\n"
+ "否则如果 分摊户数>=20 && 分摊户数<=100 则\n"
+ " 分摊用量 = 公区表_合计用量 /分摊户数*1.2\n"
+ "否则\n"
+ " 分摊用量 = 公区表_合计用量 /分摊户数*1.5\n"
+ "如果完\n"
+ "分摊用量 = round(分摊用量, 2)\n"
+ "// 计算金额\n"
+ "分摊金额 = round(分摊用量* 公区表_单价, 2)\n"
+ "分摊比例 = round(公区表_应收金额/分摊金额, 2)");
}
})
具体功能调用方式:
static String content = "数值 加压电上次读数\n" +
"数值 加压电本次读数\n" +
"数值 加压用电\n" +
"数值 用水量\n" +
"用水量=标准值+1\n" +
"如果 !!(!(max(43.3,99)-2<=66) || 1==2 && min(用水量,4)>3 || (max(44,33) > 10 && 7>9)) != true 则\n"+
"用水量=MOD(5,2)\n" +
"否则如果 用水量==26 || 1==1 则\n"+
" 加压用电=MAX(4.0038,4)+2\n" +
" 用水量=334\n" +
"否则如果 用水量==28 则\n"+
" 加压用电=MAX(4.0038,4)+3\n" +
" 用水量=335\n" +
"否则如果 1==1 则\n"+
" 加压用电=MAX(4.0038,4)+36\n" +
" 用水量=3366\n" +
"否则\n" +
" 用水量=QUOTIENT(5,2)\n" +
" 加压用电=2\n" +
"如果完\n"+
"用水量=sqrt(-43.1)\n" +
"用水量=TROWC(-43.1)\n" +
"加压用电=ROUND(((加压电本次读数+5-加压电上次读数*(加压电上次读数+加压电本次读数*(MIN(加压电本次读数,0.5)/2)))-(加压电上次读数+3)*2)*3,2)\n" ;
// 设置系统变量
HashMap<String, Object> systemVariable = Maps.newHashMap();
systemVariable.put("金额", 0.5);
systemVariable.put("编号", "SNG-001-23");
MeterCalculate meterCalculate = new MeterCalculate(content, systemVariable);
// 实例化补充系统变量
meterCalculate.putSystemVariable("标准值", 66);
// 验证表达式是否正确
meterCalculate.verifyContent();
// 执行编译,可得到相关结果
meterCalculate.compile();
// 可以得到相关变量的值
logger.info(">>>>>{}", JSON.toJSONString(meterCalculate.VARIABLE_POOL()));
Github地址:https://github.com/wanglu05/simple-calculate.git
java通过正则进行语法分析实现表达式的逻辑判断和复杂计算实现的更多相关文章
- 详解一个自己原创的正则匹配IP的表达式
这里给大家详细讲解一下一个匹配IP地址的正则表达式, 有关正则方面的知识,会在详细的讲解中提到. 在讲解之前,我先给大家介绍一下,ip地址的生成规则. IP地址,是由32位数字二进制转为四个十进制的字 ...
- Java堆栈的应用2----------中缀表达式转为后缀表达式的计算Java实现
1.堆栈-Stack 堆栈(也简称作栈)是一种特殊的线性表,堆栈的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置进行插入和删除操作,而堆栈只允许在固定一端进行插入和删除 ...
- 应用于Java中的一个开源的表达式语言(Expression Language)
OGNL(英文全称:Object Graph Navigation Language,中文名:对象导航图语言)是应用于Java中的一个开源的表达式语言(Expression Language),它被集 ...
- Java 终于在 Java 8 中引入了 Lambda 表达式。也称之为闭包或者匿名函数。
本文首发于 blog.zhaochunqi.com 转载请注明 blog.zhaochunqi.com 根据JSR 335, Java 终于在 Java 8 中引入了 Lambda 表达式.也称之为闭 ...
- Java(4)运算符及表达式
作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15201675.html 博客主页:https://www.cnblogs.com/testero ...
- java编写简单的语法分析预测程序
编译原理课程中,编了一个简单的语法分析预测程序,这个程序时根据固定的文法得到预测分析表,然后编写程序来判断表达式是否会正确推到出来. 前提是程序没有左递归符合LL(1)文法: 文法如下: E→TE' ...
- Java 8新特性-3 Lambda 表达式
在 Java 8 之前,匿名内部类,监听器和事件处理器的使用都显得很冗长,代码可读性很差. 在Java 8 之前使用匿名内部类: 例如 interface ITestPrint{ public voi ...
- java攻城师之路--复习java web之jsp入门_El表达式_JSTL标签库
JSP 技术掌握:JSP语法 + EL + JSTL 为什么sun推出 JSP技术 ? Servlet 生成网页比较复杂,本身不支持HTML语法,html代码需要通过response输出流输出,JSP ...
- Java EE学习——Quartz的Cron表达式
经历过低谷后,还是要好好学习,越失落会越来越落后. 今天写一下Cron表达式的用法,虽然是之前自己写的,也过了挺长一段时间,这次就拿出来作为回顾吧. Cron表达式是Quartz的精髓(个人觉得),比 ...
随机推荐
- Python的题目
1.将元组 (1,2,3) 和集合 {4,5,6} 合并成一个列表.2.在列表 [1,2,3,4,5,6] 首尾分别添加整型元素 7 和 0.3.反转列表 [0,1,2,3,4,5,6,7] .4.反 ...
- MySQL概述 - 一条查询sql语句的执行过程
Server层 连接器 建立连接.获取权限.维持和管理连接. 连接建立比较复杂,建议使用长连接 定期断开长连接 mysql_reset_connection指令 查询缓存 建议关闭,任何更新操作会此t ...
- 【javascript】生成二维码
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 < ...
- ModelSerializer 使用知识点_serializers.SerializerMethodField()使用场景总结
serializers.SerializerMethodField和钩子方法结合,可以实现对ModelSerializer类的一些字段进行二次加工,返回,如下:1.对以ModelSerializer的 ...
- (48)LINUX应用编程和网络编程之三Linux获取系统信息
3.3.1.关于时间的概念 3.3.1.1.GMT时间 (1)GMT是格林尼治时间,也就是格林尼治地区的当地之间. (2)GMT时间的意义?[用格林尼治的当地时间作为全球国际时间],用以描述全球性的事 ...
- 2.Python环境搭建Window、mac、linux
1.Windows安装Python详解 使用任何高级编程语言都需要有一个自己的编程环境,Python 也不例外.只要使用 Python,就必须要配置 Python 的开发和运行环境. Python 本 ...
- Java数据结构之排序---插入排序
插入排序的基本介绍: 插入排序是对想要排序的序列以插入的方式寻找该元素的适当的位置,从而达到排序的目的. 插入排序的基本思想: 把n个待排序的元素看成一个有序表和一个无序表,开始时,有序表只有一个元素 ...
- [CSP-S模拟测试]:stone(结论+桶+前缀和+差分)
题目描述 $Cab$有两行石子,每个石子上有一个字母,为$'C''A''B'$中的一个.一开始,在每行第一个石子上站着一只$lucky$,$Cab$每次可以选择一个字母,使得所站石子上字母为该字母的$ ...
- ES6 函数参数的解构赋值
function add([x, y]){ return x + y; } add([1, 2]); // 3
- Spring容器的基本使用
1)如何将一个Bean组件交给Spring容器 方法:在applicationContext.xml中添加以下定义 <bean id = “标识符” class = “Bean组件类型”> ...