基于Java的简易表达式解析工具

Posted 无处不在的海贼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于Java的简易表达式解析工具相关的知识,希望对你有一定的参考价值。

之前简单的介绍了这个基于Java表达式解析工具,现在把代码分享给大家,希望帮助到有需要的人们,这个分享代码中依赖了一些其他的类,这些类大家可以根据自己的情况进行导入,无非就是写字符串处理工具类,日期处理的工具类什么的。

这个Java的表达式解析的工具只用了5个类,而且写得也很简单明了,相信有一些编程经验的可以看懂这些处理的逻辑代码。

1、第一个类:ExpressionNodeType(表达式各个字符节点的类型枚举类)

public enum ExpressionNodeType {

    Unknown,
    Plus,// +
    Subtract, /// -
    MultiPly,// *
    Divide,// /
    LParentheses,//(
    RParentheses, /// )
    Mod,//% (求模,取余)
    Power,// ^ (次幂)
    BitwiseAnd, /// & (按位与)
    BitwiseOr,/// | (按位或)
    And,// && (逻辑与)
    Or, /// || (逻辑或)
    Not,/// ! (逻辑非)
    Equal,/// == (相等)
    Unequal,/// != 或 <> (不等于)
    GT, /// > (大于)
    LT, /// < (小于)
    GTOrEqual,/// >= (大于等于)
    LTOrEqual, /// <= (小于等于)
    LShift,  /// << (左移位)
    RShift,/// >> (右移位)
    Numeric, /// 数值,
    String,
    Date,
    Like,//包含
    NotLike,//不包含
    StartWith,//已什么开始
    EndWith//已什么结尾
	
}

这个类中定义了一些枚举的类型,如加减乘数啊,等于不等于啊,包含不包含啊,如果要进行扩展的话,第一步需要在这里定义一种枚举类型。

2、第二个类:ExpressionNode(存储表达式运算符或操作数的各个节点的类)

public class ExpressionNode {

	 private String value;
	 
	 private ExpressionNodeType type;
	 
	 private int pri;
	 
	 private ExpressionNode unitaryNode;
	 
	 private Object numeric;
	 
	/**
	 * 
	 * @param value 操作数或运算符
	 */
    public ExpressionNode(String value)
    {
        this.value = value;
        this.type = parseNodeType(value);
        this.pri = getNodeTypePRI(this.type);
        this.numeric = null;
    }

   
    public Object getNumeric(){
    	if(this.numeric == null){
    		
    		 if ((this.type == ExpressionNodeType.String) || (this.type == ExpressionNodeType.Date))
             {
                 return this.value;
             }
    		
    		 if (this.type != ExpressionNodeType.Numeric){
    			 return 0;
    		 } 
    		 Double num = new Double(this.value);
    		 if (this.unitaryNode != null && this.unitaryNode.type == ExpressionNodeType.Subtract)
             {
    			 num = 0 - num;
             }
             this.numeric =  num;
    	}
    	return numeric;
    }
    
    
    public void setNumeric(Object numeric) {
		 this.numeric = numeric;
		 this.value = this.numeric.toString();
	}
    
    /**
     * 设置或返回与当前节点相关联的一元操作符节点
     * @param unitaryNode
     */
    public void setUnitaryNode(ExpressionNode unitaryNode) {
		this.unitaryNode = unitaryNode;
	}

    /**
     *  解析节点类型
     * @param value
     * @return
     */
    private static ExpressionNodeType parseNodeType(String value)
    {
        if (StringUtils.isEmpty(value)){
        	return ExpressionNodeType.Unknown;
        } 
        switch (value)
        {
            case "+":
                return ExpressionNodeType.Plus;
            case "-":
                return ExpressionNodeType.Subtract;
            case "*":
                return ExpressionNodeType.MultiPly;
            case "/":
                return ExpressionNodeType.Divide;
            case "%":
                return ExpressionNodeType.Mod;
            case "^":
                return ExpressionNodeType.Power;
            case "(":
                return ExpressionNodeType.LParentheses;
            case ")":
                return ExpressionNodeType.RParentheses;
            case "&":
                return ExpressionNodeType.BitwiseAnd;
            case "|":
                return ExpressionNodeType.BitwiseOr;
            case "&&":
            case "<并且>":
            case "并且":
                return ExpressionNodeType.And;
            case "||":
            case "<或者>":
            case "或者":
                return ExpressionNodeType.Or;
            case "!":
                return ExpressionNodeType.Not;
            case "==":
            case "=":
                return ExpressionNodeType.Equal;
            case "!=":
            case "<>":
            case "≠":
                return ExpressionNodeType.Unequal;
            case ">":
                return ExpressionNodeType.GT;
            case "<":
                return ExpressionNodeType.LT;
            case ">=":
            case "≥":	
                return ExpressionNodeType.GTOrEqual;
            case "<=":
            case "≤":	
                return ExpressionNodeType.LTOrEqual;
            case "<<":
                return ExpressionNodeType.LShift;
            case ">>":
                return ExpressionNodeType.RShift;
            case "@":
            case "<包含>":
            case "包含":
                return ExpressionNodeType.Like;
            case "[email protected]":
            case "<不包含>":
            case "不包含":
                return ExpressionNodeType.NotLike;
            case "!!$":
                return ExpressionNodeType.StartWith;
            case "[email protected]":
                return ExpressionNodeType.EndWith;
           
        }
        if (isNumerics(value))
        {
            return ExpressionNodeType.Numeric;
        }
        if (isDatetime(value))
        {
            return ExpressionNodeType.Date;
        }
        if (value.contains("\""))
        {
            return ExpressionNodeType.String;
        }
        return ExpressionNodeType.Unknown;
    }

    /**
     * 获取各节点类型的优先级
     * @param nodeType
     * @return
     */
    private static int getNodeTypePRI(ExpressionNodeType nodeType)
    {
    	switch (nodeType)
        {
            case LParentheses:
            case RParentheses:
                return 9;
            //逻辑非是一元操作符,所以其优先级较高
            case Not:
                return 8;
            case Mod:
                return 7;
            case MultiPly:
            case Divide:
            case Power:
                return 6;
            case Plus:
            case Subtract:
                return 5;
            case LShift:
            case RShift:
                return 4;
            case BitwiseAnd:
            case BitwiseOr:
                return 3;
            case Equal:
            case Unequal:
            case GT:
            case LT:
            case GTOrEqual:
            case LTOrEqual:
            case Like:
            case NotLike:
            case StartWith:
            case EndWith:
                return 2;
            case And:
            case Or:
                return 1;
            default:
                return 0;
        }
        
    }

    /**
     * 判断是否为数值
     * @param op
     * @return
     */
    public static boolean isNumerics(String op)
    {
    	return op.matches("^[\\+\\-]?(0|[1-9]\\d*|[1-9]\\d*\\.\\d+|0\\.\\d+)");
    }

    /**
     * 判断是否为日期
     * @param op
     * @return
     */
    public static boolean isDatetime(String op)
    {
    	op = op.replace("\"","").trim();
        return op.matches("\\d{4}\\-\\d{2}\\-\\d{2}(\\s\\d{2}\\:\\d{2}\\:\\d{2})?");
    }

    
    /**
     * 判断某个字符后是否需要更多的操作符
     * @param c
     * @return
     */
    public static boolean needMoreOperator(char c)
    {
        switch (c)
        {
            case ‘&‘:
            case ‘|‘:
            case ‘=‘:
            case ‘!‘:
            case ‘>‘:
            case ‘<‘:
            case ‘.‘:   //小数点
                return true;
        }
//        //数字则需要更多
        return Character.isDigit(c);
    }

    /**
     * 判断两个字符是否是同一类
     * @param c1
     * @param c2
     * @return
     */
    public static boolean IsCongener(char c1, char c2)
    {
    	 if ((c1 == ‘(‘) || (c2 == ‘(‘)){
             return false;
         }
         if ((c1 == ‘)‘) || (c2 == ‘)‘)){
             return false;
         }
         if ((c1 == ‘"‘) || (c2 == ‘"‘)){
             return false;
         }
         if (Character.isDigit(c1) || (c1 == ‘.‘))
         {
        	//c1为数字,则c2也为数字
             return (Character.isDigit(c2) || (c2 == ‘.‘));
         }
         return (!Character.isDigit(c2) && (c2 != ‘.‘));
    }

    /**
     * 判断某个字符是否是空白字符
     * @param c
     * @return
     */
    public static boolean IsWhileSpace(char c)
    {
        return c == ‘ ‘ || c == ‘\t‘;
    }

    /**
     * 判断是否是一元操作符节点
     * @param nodeType
     * @return
     */
    public static boolean IsUnitaryNode(ExpressionNodeType nodeType)
    {
        return (nodeType == ExpressionNodeType.Plus || nodeType == ExpressionNodeType.Subtract);
    }

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}

	public ExpressionNodeType getType() {
		return type;
	}

	public void setType(ExpressionNodeType type) {
		this.type = type;
	}

	public int getPri() {
		return pri;
	}

	public void setPri(int pri) {
		this.pri = pri;
	}

	public ExpressionNode getUnitaryNode() {
		return unitaryNode;
	}

当需要解析一个表达式时,会把表达式中的每个字符生生成一个ExpressionNode对象,并存储了这个字符的节点类型,字符后面是否有其他字符等一些信息。

3、第三个类:ExpressionException(表达式异常类)

public class ExpressionException extends RuntimeException{

	private static final long serialVersionUID = 1L;

	public ExpressionException() {
		super();
	}

	public ExpressionException(String msg) {
		super(msg);
	}
	
	public ExpressionException(String msg, Throwable cause) {
		super(msg,cause);
	}
	
	public ExpressionException(Throwable cause) {
		super(cause);
	}
}

4、第四个类:ExpressionParser(负责读取表达式生成ExpressionNode对象的类)

public class ExpressionParser {

	//当前分析的表达式
	private String expression;
	
	//当前读取的位置
	private int position;
	
	public String getExpression() {
		return expression;
	}

	public void setExpression(String expression) {
		this.expression = expression;
	}

	public int getPosition() {
		return position;
	}

	public void setPosition(int position) {
		this.position = position;
	}

	public ExpressionParser(String expression)
	{
		this.expression = expression;
		this.position = 0;
	}

	/**
	 *  读取下一个表达式节点,如果读取失败则返回null
	 * @return
	 */
    public ExpressionNode readNode()
    {
        //空格的位置
        int whileSpacePos = -1;
        boolean flag = false;
        StringBuffer buffer = new StringBuffer(10);
        while (this.position < this.expression.length())
        {
            char c = this.expression.charAt(this.position);
            if (c == ‘"‘)
            {
                flag = !flag;
                if (!flag)
                {
                    this.position++;
                    buffer.append(c);
                    break;
                }
                if (buffer.length() != 0)
                {
                    break;
                }
            }
            if (flag)
            {
                this.position++;
                buffer.append(c);
            }
            else
            {
                if (ExpressionNode.IsWhileSpace(c))
                {
                    if ((whileSpacePos >= 0) && ((this.position - whileSpacePos) > 1))
                    {
                        throw new ExpressionException(String.format("表达式\"%s\"在位置(%s)上的字符非法!", this.getExpression(), this.getPosition()));
                    }
                    if (buffer.length() == 0)
                    {
                    	whileSpacePos = -1;
                    }
                    else
                    {
                    	whileSpacePos = this.position;
                    }
                    this.position++;
                    continue;
                }
                if ((buffer.length() == 0) || ExpressionNode.IsCongener(c, buffer.charAt(buffer.length() - 1)))
                {
                    this.position++;
                    buffer.append(c);
                }
                else
                {
                    break;
                }
                if (!ExpressionNode.needMoreOperator(c))
                {
                    break;
                }
            }
        }
        if (buffer.length() == 0)
        {
            return null;
        }
        ExpressionNode node = new ExpressionNode(buffer.toString());
        if (node.getType() == ExpressionNodeType.Unknown)
        {
            throw new ExpressionException(String.format("表达式\"%s\"在位置%s上的字符\"%s\"非法!", this.getExpression(), this.getPosition() - node.getValue().length(), node.getValue()));
        }
        return node;
    }
	
}

这个类处理将待解析的表达式,解析并创建ExpressionNode对象。

5、第五个类:ExpressionEvaluator(解析公式并返回结果的类)

public class ExpressionEvaluator {

	 private ExpressionEvaluator()
     {
		 
     }
	
	 /**
	  * 将算术表达式转换为逆波兰表达式
	  * @param expression 要计算的表达式,如"1+2+3+4"
	  * @return
	  */
	 private static List<ExpressionNode> parseExpression(String expression)
     {
		 if(StringUtils.isEmpty(expression)){
			 return new ArrayList<ExpressionNode>();
		 }

         List<ExpressionNode> listOperator = new ArrayList<ExpressionNode>(10);
         Stack<ExpressionNode> stackOperator = new Stack<ExpressionNode>();

         ExpressionParser expParser = new ExpressionParser(expression);
         ExpressionNode beforeExpNode = null;       //前一个节点            
         ExpressionNode unitaryNode = null;         //一元操作符
         ExpressionNode expNode;

         //是否需要操作数
         boolean requireOperand = false;


         while ((expNode = expParser.readNode()) != null)
         {
             if ( (expNode.getType() == ExpressionNodeType.Numeric) || 
            		 (expNode.getType() == ExpressionNodeType.String) || 
            		 (expNode.getType() == ExpressionNodeType.Date))
             {
                 //操作数, 直接加入后缀表达式中
                 if (unitaryNode != null)
                 {
                     //设置一元操作符节点
                     expNode.setUnitaryNode(unitaryNode);
                     unitaryNode = null;
                 }

                 listOperator.add(expNode);
                 requireOperand = false;
                 continue;
             }
             else if (expNode.getType() == ExpressionNodeType.LParentheses)
             {
                 //左括号, 直接加入操作符栈
            	 stackOperator.push(expNode);
            	 continue;
             }
             else if (expNode.getType() == ExpressionNodeType.RParentheses)
             {
                 //右括号则在操作符栈中反向搜索,直到遇到匹配的左括号为止,将中间的操作符依次加到后缀表达式中。
                 ExpressionNode lpNode = null;
                 while (stackOperator.size() > 0)
                 {
                     lpNode = stackOperator.pop();
                     if (lpNode.getType() == ExpressionNodeType.LParentheses) break;
                     listOperator.add(lpNode);
                 }
                 if (lpNode == null || lpNode.getType() != ExpressionNodeType.LParentheses)
                 {
                     throw new ExpressionException(String.format("在表达式\"%s\"中没有与在位置(%s)上\")\"匹配的\"(%s)\"字符!", expParser.getExpression(), expParser.getPosition()));
                 }
             }
             else
             {
                 if (stackOperator.size() == 0)
                 {
                     //第一个节点则判断此节点是否是一元操作符"+,-,!,("中的一个,否则其它都非法
                     if (listOperator.size() == 0 &&
                         !(expNode.getType() == ExpressionNodeType.LParentheses || expNode.getType() == ExpressionNodeType.Not))
                     {
                         //后缀表达式没有任何数据则判断是否是一元操作数
                         if (ExpressionNode.IsUnitaryNode(expNode.getType()))
                         {
                             unitaryNode = expNode;
                         }
                         else
                         {
                             //丢失操作数
                             throw new ExpressionException(String.format("表达式\"%s\"在位置(%s)上缺少操作数!", expParser.getExpression(), expParser.getPosition()));
                         }
                     }
                     else
                     {
                         //直接压入操作符栈
                         stackOperator.push(expNode);
                     }
                     requireOperand = true;          //下一个节点需要操作数
                     continue;
                 }
                 else
                 {
                     if (requireOperand)
                     {
                         //如果需要操作数则判断当前的是否是"+","-"号(一元操作符),如果是则继续
                         if (ExpressionNode.IsUnitaryNode(expNode.getType()) && unitaryNode == null)
                         {
                             unitaryNode = expNode;
                         }
                         else
                         {
                             //丢失操作数
                             throw new ExpressionException(String.format("表达式\"%s\"在位置({1})上缺少操作数!", expParser.getExpression(), expParser.getPosition()));
                         }
                     }
                     else
                     {
                         //对前面的所有操作符进行优先级比较
                         do
                         {
                             //取得上一次的操作符
                             beforeExpNode = stackOperator.peek();

                             //如果前一个操作符优先级较高,则将前一个操作符加入后缀表达式中
                             if (beforeExpNode.getType() != ExpressionNodeType.LParentheses && (beforeExpNode.getPri() - expNode.getPri()) >= 0)
                             {
                                 listOperator.add(stackOperator.pop());
                             }
                             else
                             {
                                 break;
                             }

                         } while (stackOperator.size() > 0);

                         //将操作符压入操作符栈
                         stackOperator.push(expNode);
                         requireOperand = true;
                     }
                 }
             }
         }

         if (requireOperand)
         {
             //丢失操作数
             throw new ExpressionException(String.format("表达式\"%s\"在位置({1})上缺少操作数!", expParser.getExpression(), expParser.getPosition()));
         }
         //清空堆栈
         while (stackOperator.size() > 0)
         {
             //取得操作符
             beforeExpNode = stackOperator.pop();
             if (beforeExpNode.getType() == ExpressionNodeType.LParentheses)
             {
                 throw new ExpressionException(String.format("表达式\"%s\"中括号不匹配,丢失右括号!", expParser.getExpression(), expParser.getPosition()));
             }
             listOperator.add(beforeExpNode);
         }

         return listOperator;
     }
	
	 /**
	  * 对逆波兰表达式进行计算
	  * @param nodes
	  * @return
	  */
     private static Object CalcExpression(List<ExpressionNode> nodes)
     {
         if (nodes == null || nodes.size() == 0) return null;

         if (nodes.size() > 1)
         {
             int index = 0;
             //储存数据
             ArrayList values = new ArrayList();
             while (index < nodes.size())
             {
                 ExpressionNode node = nodes.get(index);
                 		
                 switch (node.getType())
                 {
                     //如果是数字,则将值存入 values 中
                     case Numeric:
                     case String:
                     case Date:
                         values.add(node.getNumeric());
                         index++;
                         break;
                     default:   
	                	 //二元表达式,需要二个参数, 如果是Not的话,则只要一个参数
	                     int paramCount = 2;
	                     if (node.getType() == ExpressionNodeType.Not) paramCount = 1;
	                     //计算操作数的值
	                     if (values.size() < paramCount)
	                     {
	                         throw new ExpressionException("缺少操作数");
	                     }
	                     //传入参数
	                     Object[] data = new Object[paramCount];
	                     for (int i = 0; i < paramCount; i++)
	                     {
	                         data[i] = values.get(index - paramCount + i);
	                     }
	                     //将计算结果再存入当前节点
	                     node.setNumeric(calculate(node.getType(), data));
	                     node.setType( ExpressionNodeType.Numeric);
	                     //将操作数节点删除
	                     for (int i = 0; i < paramCount; i++)
	                     {
	                         nodes.remove(index - i - 1);
	                         values.remove(index - i - 1);
	                     }
	                     index -= paramCount;
	                     break;
                 }
                 
             }
         }

         if (nodes.size() != 1)
         {
             throw new ExpressionException("缺少操作符或操作数");
         }
         switch (nodes.get(0).getType())
         {
             case Numeric:
                 return nodes.get(0).getNumeric();

             case String:
             case Date:
                 return nodes.get(0).getNumeric().toString().replace("\"", "");
         }
         throw new ExpressionException("缺少操作数");
     }
     
     /**
      * 计算节点的值
      * @param nodeType 节点的类型
      * @param data 要计算的值,有可能是两位或一位数
      * @return
      */
     private static Object calculate(ExpressionNodeType nodeType, Object[] data)
     {
         double d1, d2;
         boolean  b1, b2;
         Date time1,time2;
         Object obj1 = data[0];
         Object obj2 = data[1];
         String str1 = obj1.toString();
         String str2 = obj2.toString();
         
         boolean dateflag = ExpressionNode.isDatetime(str1) || ExpressionNode.isDatetime(str2);
         boolean strflag = str1.contains("\"") || str2.contains("\"");
         str1 = str1.replace("\"", "");
         str2 = str2.replace("\"", "");
         
         switch (nodeType)
         {
             case Plus:
            	 if (!strflag)
                 {
                	 d1 = ConvertToDecimal(obj1);
                     d2 = ConvertToDecimal(obj2);
                     return (d1 + d2);
                 }
                 return new StringBuffer(str1 + str2).toString();
             case Subtract:
                 d1 = ConvertToDecimal(obj1);
                 d2 = ConvertToDecimal(obj2);
                 return d1 - d2;
             case MultiPly:
                 d1 = ConvertToDecimal(obj1);
                 d2 = ConvertToDecimal(obj2);
                 return d1 * d2;
             case Divide:
                 d1 = ConvertToDecimal(obj1);
                 d2 = ConvertToDecimal(obj2);
                 if (d2 == 0)throw new RuntimeException();
                 return d1 / d2;
             case Power:
                 d1 = ConvertToDecimal(obj1);
                 d2 = ConvertToDecimal(obj2);
                 return Math.pow((double)d1, (double)d2);
             case Mod:
                 d1 = ConvertToDecimal(obj1);
                 d2 = ConvertToDecimal(obj2);
                 if (d2 == 0) throw new RuntimeException();
                 return d1 % d2;
             case BitwiseAnd:
                 d1 = ConvertToDecimal(obj1);
                 d2 = ConvertToDecimal(obj2);
                 return (int)d1 & (int)d2;
             case BitwiseOr:
                 d1 = ConvertToDecimal(obj1);
                 d2 = ConvertToDecimal(obj2);
                 return (int)d1 | (int)d2;
             case And:
                 b1 = ConvertToBool(obj1);
                 b2 = ConvertToBool(obj2);
                 return b1 && b2;
             case Or:
                 b1 = ConvertToBool(obj1);
                 b2 = ConvertToBool(obj2);
                 return b1 || b2;
             case Not:
                 b1 = ConvertToBool(obj1);
                 return !b1;
             case Equal:
            	 if (!dateflag)
                 {
                     if (strflag)
                     {
                         return str1.equals(str2);
                     }
                     d1 = ConvertToDecimal(obj1);
                     d2 = ConvertToDecimal(obj2);
                     return (d1 == d2);
                 }
            	 time1 = DateUtils.parse(str1);
            	 time2 = DateUtils.parse(str2);
                 
                 return (time1.getTime() == time2.getTime());
             case Unequal:
            	 if (!dateflag)
                 {
                     if (strflag)
                     {
                         return (!str1.equals(str2));
                     }
                     d1 = ConvertToDecimal(obj1);
                     d2 = ConvertToDecimal(obj2);
                     return (d1 != d2);
                 }
            	 time1 = DateUtils.parse(str1);
            	 time2 = DateUtils.parse(str2);
                 
                 return (time1.getTime() != time2.getTime());
             case GT:
            	 
            	 if (!dateflag)
                 {
                     d1 = ConvertToDecimal(obj1);
                     d2 = ConvertToDecimal(obj2);
                     return (d1 > d2);
                 }
            	 time1 = DateUtils.parse(str1);
            	 time2 = DateUtils.parse(str2);
            	 return (time1.getTime() > time2.getTime());
            	 
             case LT:
            	 
            	 if (!dateflag)
                 {
                     d1 = ConvertToDecimal(obj1);
                     d2 = ConvertToDecimal(obj2);
                     return (d1 < d2);
                 }
            	 time1 = DateUtils.parse(str1);
            	 time2 = DateUtils.parse(str2);
            	 return (time1.getTime() < time2.getTime());
            	 
             case GTOrEqual:
            	 
            	 if (!dateflag)
                 {
                     d1 = ConvertToDecimal(obj1);
                     d2 = ConvertToDecimal(obj2);
                     return (d1 >= d2);
                 }
            	 time1 = DateUtils.parse(str1);
            	 time2 = DateUtils.parse(str2);
                 return (time1.getTime() >= time2.getTime());
            	 
             case LTOrEqual:
            	 if (!dateflag)
                 {
                     d1 = ConvertToDecimal(obj1);
                     d2 = ConvertToDecimal(obj2);
                     return (d1 <= d2);
                 }
            	 time1 = DateUtils.parse(str1);
            	 time2 = DateUtils.parse(str2);
                 return (time1.getTime() <= time2.getTime());
             case LShift:
                 d1 = ConvertToDecimal(obj1);
                 d2 = ConvertToDecimal(obj2);
                 return (long)d1 << (int)d2;
                 
             case RShift:
                 d1 = ConvertToDecimal(obj1);
                 d2 = ConvertToDecimal(obj2);
                 return (long)d1 >> (int)d2;
             case Like:
                 if (!strflag)
                 {
                     return false;
                 }
                 return str1.contains(str2);
             case NotLike:
                 if (!strflag)
                 {
                     return false;
                 }
                 return !str1.contains(str2);
             case StartWith:
                 if (!strflag)
                 {
                     return false;
                 }
                 return str1.startsWith(str2);
             case EndWith:
                 if (!strflag)
                 {
                     return false;
                 }
                 return str1.endsWith(str2);      
         }
         
         return 0;
     }
	
     /**
      * 某个值转换为bool值
      * @param value
      * @return
      */
     private static Boolean ConvertToBool(Object value)
     {
         if (value instanceof Boolean){
             return (Boolean)value;
         }
         else{
             return value != null;
         }
     }

     /**
      * 将某个值转换为decimal值
      * @param value
      * @return
      */
     private static Double ConvertToDecimal(Object value)
     {
         if (value instanceof Boolean)
         {
             return ((Boolean)value ? 1d : 0d);
         }
         else
         {
             return Double.parseDouble(value.toString());
         }
     }
	
     /**
      * 
      * @param expression 要计算的表达式,如"1+2+3+4"
      * @return 返回计算结果,如果带有逻辑运算符则返回true/false,否则返回数值
      */
     public static Object eval(String expression)
     {
         return CalcExpression(parseExpression(expression));
     }
     
     public static Object evalThreeOperand(String expression)
     {
         int index = expression.indexOf("?");
         if (index > -1)
         {
             String str = expression.substring(0, index);
             String str2 = expression.substring(index + 1);
             index = str2.indexOf(":");
            
             if ( Boolean.parseBoolean((CalcExpression(parseExpression(str))).toString()))
             {
                 return eval(str2.substring(0, index));
             }
             return eval(str2.substring(index + 1));
         }
         return CalcExpression(parseExpression(expression));
     }
     
}

这个类是最重要的一个类,parseExpression方法会将待解析的表达式转变为ExpressionNode的集合,calculate方法会将两个值进行各种运算操作,也是在这个方法中,我们填写扩展的一些方法。

这个工具的介绍就这些了,希望可以帮助到有需要的人。



以上是关于基于Java的简易表达式解析工具的主要内容,如果未能解决你的问题,请参考以下文章

基于Java Swing编写的简易运费计算工具

基于Java Swing编写的简易运费计算工具

通过 Java 正则表达式提取 semver 版本字符串的片段

简易前端模板引擎

片段(Java) | 机试题+算法思路+考点+代码解析 2023

正则表达式之简易markdown文件解析器