zoukankan      html  css  js  c++  java
  • 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("数值 分摊比例
    "
                        + "数值 分摊单价
    "
                        + "
    "
                        + "分摊单价 = 公区表_单价
    "
                        + "// 条件判断户数大于10
    "
                        + "如果 分摊户数<=10 则
    "
                        + "    分摊用量 =  公区表_合计用量/分摊户数*0.8
    "
                        + "否则如果 分摊户数>10 && 分摊户数<20 则
    "
                        + "    分摊用量 =  公区表_合计用量 /分摊户数
    "
                        + "否则如果 分摊户数>=20 && 分摊户数<=100 则
    "
                        + "    分摊用量 =  公区表_合计用量 /分摊户数*1.2
    "
                        + "否则
    "
                        + "    分摊用量 =  公区表_合计用量 /分摊户数*1.5
    "
                        + "如果完
    "
                        + "分摊用量 = round(分摊用量, 2)
    "
                        + "// 计算金额
    "
                        + "分摊金额 = round(分摊用量* 公区表_单价, 2)
    "
                        + "分摊比例 =  round(公区表_应收金额/分摊金额, 2)");
        }
    })

     具体功能调用方式:

     static String content = "数值 加压电上次读数
    " +
            "数值 加压电本次读数
    " +
            "数值 加压用电
    " +
            "数值     用水量
    " +
            "用水量=标准值+1
    " +
            "如果 !!(!(max(43.3,99)-2<=66) || 1==2 && min(用水量,4)>3 || (max(44,33) > 10 &&  7>9)) != true 则
    "+
            "用水量=MOD(5,2)
    " +
            "否则如果 用水量==26 || 1==1 则
    "+
            "   加压用电=MAX(4.0038,4)+2
    " +
            "   用水量=334
    " +
            "否则如果 用水量==28 则
    "+
            "   加压用电=MAX(4.0038,4)+3
    " +
            "   用水量=335
    " +
            "否则如果 1==1 则
    "+
            "   加压用电=MAX(4.0038,4)+36
    " +
            "   用水量=3366
    " +
            "否则
    " +
            "   用水量=QUOTIENT(5,2)
    " +
            "   加压用电=2
    " +
            "如果完
    "+
            "用水量=sqrt(-43.1)
    " +
            "用水量=TROWC(-43.1)
    " +
            "加压用电=ROUND(((加压电本次读数+5-加压电上次读数*(加压电上次读数+加压电本次读数*(MIN(加压电本次读数,0.5)/2)))-(加压电上次读数+3)*2)*3,2)
    " ;
         
    // 设置系统变量 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

  • 相关阅读:
    Oracle数据库的非归档模式迁移到归档模式
    对Dataguard的三种模式的理解
    RMAN中建立Catalog 用数据库的例子
    Oracle中实现dblink的作法
    expdp 简单例子
    Oracle单节点_Grid_Infrastructure_DB_安装过程图解(三/三)
    Oracle单节点_Grid_Infrastructure_DB_安装过程图解(一/三)
    Oracle单节点_Grid_Infrastructure_DB_安装过程图解(二/三)
    Oracle 安装过程中 File not found "WFMLRSVCApp.ear" 的原因
    基于Django的在线考试系统
  • 原文地址:https://www.cnblogs.com/wanglu/p/11394355.html
Copyright © 2011-2022 走看看