zoukankan      html  css  js  c++  java
  • 自定义表达式解析器

    解析器:

    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.regex.Pattern;
    
    import javax.script.ScriptEngine;
    import javax.script.ScriptEngineManager;
    import javax.script.ScriptException;
    
    import com.tf.arithmetic.bean.Exterior;
    
    /**
     * 自定义计算表达式解析器和计算器
     * 表达式的写法:@{占位变量}
     * @author yzl
     *
     */
    public class ExpressionResolver {
        private ExpressionResolver(){}
        private static ExpressionResolver resolver = null;
        public static ExpressionResolver getInstance(){
            if(null==resolver){
                resolver = new ExpressionResolver();
            }
            return resolver;
        }
        
        /**
         * 计算表达式的结果
         * @param expression  解析包含@{}的表达式
         * @param bean
         * @param precision
         * @return
         * @throws ScriptException
         * @throws NoSuchMethodException
         * @throws SecurityException
         * @throws IllegalAccessException
         * @throws IllegalArgumentException
         * @throws InvocationTargetException
         */
        public double getExecuteResult(String expression, Object bean, int precision) throws ScriptException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
            expression = this.parse(expression, bean);
            ScriptEngine se = new ScriptEngineManager().getEngineByName("JavaScript");
            double result = (Double) se.eval(expression);
            return MathUtils.multiply(result, 1d, precision);
        }
        
        /**
         * 解析自定义的@{}表达式
         * (@{ys}*0.3+@{csd}*0.25+@{jg}*0.15+@{sf}*0.12+@{yf}*0.1+@{sd}*0.08)*10
         * @param expression
         * @param bean
         * @return
         * @throws SecurityException 
         * @throws NoSuchMethodException 
         * @throws InvocationTargetException 
         * @throws IllegalArgumentException 
         * @throws IllegalAccessException 
         */
        private String parse(String expression, Object bean) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
            //保存表达式中的所有变量
            List<String> variableList = new ArrayList<String>();
            
            String reg = "@\{";
            String reg2 = "\}";
            Pattern pattern = Pattern.compile(reg);
            Pattern pattern2 = Pattern.compile(reg2);
            String[] arr = pattern.split(expression);
            for(int i=0; i<arr.length; i++){
                if(!"(".equals(arr[i]) && !")".equals(arr[i])){
                    variableList.add(pattern2.split(arr[i])[0]);
                }
            }
            
            String fieldName = null;
            String methodName = null;
            Object result = null;
            
            //用值替换表达式中的变量
            if(variableList.size()>0){
                Field[] field = bean.getClass().getDeclaredFields();
                for(int i=0; i<field.length; i++){
                    fieldName = field[i].getName();
                    methodName = "get"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);
                    result = bean.getClass().getMethod(methodName, null).invoke(bean);
                    expression = expression.replace("@{"+fieldName+"}", result.toString());
                }
            }
            
            return expression;
        }
        
        public static void main(String[] args) throws Exception {
            String input = "(@{ys}*0.3+@{csd}*0.25+@{jg}*0.15+@{sf}*0.12+@{yf}*0.1+@{sd}*0.08)*10";
            String reg = "@\{";
            String reg2 = "\}";
            Pattern pattern = Pattern.compile(reg);
            Pattern pattern2 = Pattern.compile(reg2);
            String[] arr = pattern.split(input);
            for(int i=0; i<arr.length; i++){
                if(!"(".equals(arr[i]) && !")".equals(arr[i])){
                    System.out.println("得到变量:"+pattern2.split(arr[i])[0]);
                }
            }
            
            Exterior bean = new Exterior(8,8,8,8,8,8);
            double val = ExpressionResolver.getInstance().getExecuteResult(input, bean, 2);
            System.out.println(val);
        }
    }

    需要的实体bean(例子):

    /**
     * 某模型的pojo对象
     * @author yzl
     *
     */
    public class Exterior {
        private int ys;
        private int csd;
        private int jg;
        private int sf;
        private int yf;
        private int sd;
        
        public int getYs() {
            return ys;
        }
        public void setYs(int ys) {
            this.ys = ys;
        }
        public int getCsd() {
            return csd;
        }
        public void setCsd(int csd) {
            this.csd = csd;
        }
        public int getJg() {
            return jg;
        }
        public void setJg(int jg) {
            this.jg = jg;
        }
        public int getSf() {
            return sf;
        }
        public void setSf(int sf) {
            this.sf = sf;
        }
        public int getYf() {
            return yf;
        }
        public void setYf(int yf) {
            this.yf = yf;
        }
        public int getSd() {
            return sd;
        }
        public void setSd(int sd) {
            this.sd = sd;
        }
        
        public Exterior(int ys, int csd, int jg, int sf, int yf, int sd) {
            super();
            this.ys = ys;
            this.csd = csd;
            this.jg = jg;
            this.sf = sf;
            this.yf = yf;
            this.sd = sd;
        }
        
        public Exterior() {
            super();
        }
    }
  • 相关阅读:
    pycharm鼠标光标变成黑色方块
    华章8月书讯,夏日静心好读书
    测试既是一门科学,也是一门艺术
    计算机科学与技术专业教指委将成立“物联网工程专业教学研究专家组”
    【七夕送好书】转微博获赠书!
    孟岩谈《C++程序设计原理与实践》
    【有奖活动】华章IT15周年,评选您心中最有影响力的10种图书
    《测试之美》连载:创建开源的QA社区
    Web前端开发之“常见模块你真的很了解吗?”
    测试驱动开发简介
  • 原文地址:https://www.cnblogs.com/yangzhilong/p/4213472.html
Copyright © 2011-2022 走看看