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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM