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();
        }
    }
  • 相关阅读:
    Atcoder D
    51nod 1201 整数划分(dp)
    Atcoder D
    Atcoder C
    codeforces 812 E. Sagheer and Apple Tree(树+尼姆博弈)
    codeforces 811 D. Vladik and Favorite Game(bfs水题)
    codeforces 811 E. Vladik and Entertaining Flags(线段树+并查集)
    codeforces 811 C. Vladik and Memorable Trip(dp)
    1449 砝码称重(思维)
    SQL大量数据查询的优化 及 非用like不可时的处理方案
  • 原文地址:https://www.cnblogs.com/yangzhilong/p/4213472.html
Copyright © 2011-2022 走看看