首先功能展示:

  

相关功能实现,实现功能类似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通过正则进行语法分析实现表达式的逻辑判断和复杂计算实现的更多相关文章

  1. 详解一个自己原创的正则匹配IP的表达式

    这里给大家详细讲解一下一个匹配IP地址的正则表达式, 有关正则方面的知识,会在详细的讲解中提到. 在讲解之前,我先给大家介绍一下,ip地址的生成规则. IP地址,是由32位数字二进制转为四个十进制的字 ...

  2. Java堆栈的应用2----------中缀表达式转为后缀表达式的计算Java实现

    1.堆栈-Stack 堆栈(也简称作栈)是一种特殊的线性表,堆栈的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置进行插入和删除操作,而堆栈只允许在固定一端进行插入和删除 ...

  3. 应用于Java中的一个开源的表达式语言(Expression Language)

    OGNL(英文全称:Object Graph Navigation Language,中文名:对象导航图语言)是应用于Java中的一个开源的表达式语言(Expression Language),它被集 ...

  4. Java 终于在 Java 8 中引入了 Lambda 表达式。也称之为闭包或者匿名函数。

    本文首发于 blog.zhaochunqi.com 转载请注明 blog.zhaochunqi.com 根据JSR 335, Java 终于在 Java 8 中引入了 Lambda 表达式.也称之为闭 ...

  5. Java(4)运算符及表达式

    作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15201675.html 博客主页:https://www.cnblogs.com/testero ...

  6. java编写简单的语法分析预测程序

    编译原理课程中,编了一个简单的语法分析预测程序,这个程序时根据固定的文法得到预测分析表,然后编写程序来判断表达式是否会正确推到出来. 前提是程序没有左递归符合LL(1)文法: 文法如下: E→TE' ...

  7. Java 8新特性-3 Lambda 表达式

    在 Java 8 之前,匿名内部类,监听器和事件处理器的使用都显得很冗长,代码可读性很差. 在Java 8 之前使用匿名内部类: 例如 interface ITestPrint{ public voi ...

  8. java攻城师之路--复习java web之jsp入门_El表达式_JSTL标签库

    JSP 技术掌握:JSP语法 + EL + JSTL 为什么sun推出 JSP技术 ? Servlet 生成网页比较复杂,本身不支持HTML语法,html代码需要通过response输出流输出,JSP ...

  9. Java EE学习——Quartz的Cron表达式

    经历过低谷后,还是要好好学习,越失落会越来越落后. 今天写一下Cron表达式的用法,虽然是之前自己写的,也过了挺长一段时间,这次就拿出来作为回顾吧. Cron表达式是Quartz的精髓(个人觉得),比 ...

随机推荐

  1. 【shell】文本匹配问题

    原文本通过TITLE分段 TITLE1 xxx yyy TITLE2 xxx yyy hello zzz hello TITLE3 xxx hello 类似于这样的,hello可能有多个,需要打印出含 ...

  2. Zabbix4.x安装部署

    zabbix监控的重要性就不用再赘述了.直接上干货. 1.环境背景: Linux:CentOS 7.x, Database:MySQL zabbix server 和 zabbix mysql 安装在 ...

  3. IDEA mapping箭头要怎么样设置哈(Free MyBatis插件)

    效果如下图: 当我们点击箭头的时候,会快速切换到我们相关联的类位置,就不用再像以前一样还要去找 而 Free MyBatis是一款让我们操作更加方便的插件,你值得拥有哦~~~ idea 选择 File ...

  4. 一个用于格式化和处理数字的javascript库----Numeral.js

    npm地址:https://www.npmjs.com/package/numeral 1.转化成百分比: numeral(num).format('0.00%')

  5. luogu 4059 [Code+#1]找爸爸 动态规划

    Description 小A最近一直在找自己的爸爸,用什么办法呢,就是DNA比对.小A有一套自己的DNA序列比较方法,其最终目标是最 大化两个DNA序列的相似程度,具体步骤如下:1.给出两个DNA序列 ...

  6. JS数据容量单位转换(kb,mb,gb,tb)

    JS代码如下: var size = '8164674'; function bytesToSize(bytes) { if (bytes === 0) return '0 B'; var k = 1 ...

  7. 举例子说明ubuntu中remove,autoremove,purge区别

    转自:慎用 apt-get autoremove !   apt-get 提供了一个用于下载和安装软件包的简易命令行界面.卸载软件包主要有这3个命令 remove – 卸载软件包autoremove ...

  8. Spring Cloud Stream教程(四)消费群体

    虽然发布订阅模型可以轻松地通过共享主题连接应用程序,但通过创建给定应用程序的多个实例来扩展的能力同样重要.当这样做时,应用程序的不同实例被放置在竞争的消费者关系中,其中只有一个实例预期处理给定消息. ...

  9. sqli-labs(23)

    基于get的过滤了的注入 0X1测试闭合 /?id=' http://127.0.0.1/sql1/Less-23/?id=1%27%27 0X02 然后就是组合拳的操作了 未报错 那么应该是’闭合 ...

  10. [ git ] eclipse如何与git 配合工作。

    原文链接http://blog.csdn.NET/yangzhihello/article/details/11003941 呵呵,看看这个吧.先去安装eclipse.然后在现在 egit,应该可以从 ...