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

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

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

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

 

[java] view plain copy
 
 print?
  1. public enum ExpressionNodeType {  
  2.   
  3.     Unknown,  
  4.     Plus,// +  
  5.     Subtract, /// -  
  6.     MultiPly,// *  
  7.     Divide,// /  
  8.     LParentheses,//(  
  9.     RParentheses, /// )  
  10.     Mod,//% (求模,取余)  
  11.     Power,// ^ (次幂)  
  12.     BitwiseAnd, /// & (按位与)  
  13.     BitwiseOr,/// | (按位或)  
  14.     And,// && (逻辑与)  
  15.     Or, /// || (逻辑或)  
  16.     Not,/// ! (逻辑非)  
  17.     Equal,/// == (相等)  
  18.     Unequal,/// != 或 <> (不等于)  
  19.     GT, /// > (大于)  
  20.     LT, /// < (小于)  
  21.     GTOrEqual,/// >= (大于等于)  
  22.     LTOrEqual, /// <= (小于等于)  
  23.     LShift,  /// << (左移位)  
  24.     RShift,/// >> (右移位)  
  25.     Numeric, /// 数值,  
  26.     String,  
  27.     Date,  
  28.     Like,//包含  
  29.     NotLike,//不包含  
  30.     StartWith,//已什么开始  
  31.     EndWith//已什么结尾  
  32.       
  33. }  

 

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

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

 

[java] view plain copy
 
 print?
  1. public class ExpressionNode {  
  2.   
  3.      private String value;  
  4.        
  5.      private ExpressionNodeType type;  
  6.        
  7.      private int pri;  
  8.        
  9.      private ExpressionNode unitaryNode;  
  10.        
  11.      private Object numeric;  
  12.        
  13.     /** 
  14.      *  
  15.      * @param value 操作数或运算符 
  16.      */  
  17.     public ExpressionNode(String value)  
  18.     {  
  19.         this.value = value;  
  20.         this.type = parseNodeType(value);  
  21.         this.pri = getNodeTypePRI(this.type);  
  22.         this.numeric = null;  
  23.     }  
  24.   
  25.      
  26.     public Object getNumeric(){  
  27.         if(this.numeric == null){  
  28.               
  29.              if ((this.type == ExpressionNodeType.String) || (this.type == ExpressionNodeType.Date))  
  30.              {  
  31.                  return this.value;  
  32.              }  
  33.               
  34.              if (this.type != ExpressionNodeType.Numeric){  
  35.                  return 0;  
  36.              }   
  37.              Double num = new Double(this.value);  
  38.              if (this.unitaryNode != null && this.unitaryNode.type == ExpressionNodeType.Subtract)  
  39.              {  
  40.                  num = 0 - num;  
  41.              }  
  42.              this.numeric =  num;  
  43.         }  
  44.         return numeric;  
  45.     }  
  46.       
  47.       
  48.     public void setNumeric(Object numeric) {  
  49.          this.numeric = numeric;  
  50.          this.value = this.numeric.toString();  
  51.     }  
  52.       
  53.     /** 
  54.      * 设置或返回与当前节点相关联的一元操作符节点 
  55.      * @param unitaryNode 
  56.      */  
  57.     public void setUnitaryNode(ExpressionNode unitaryNode) {  
  58.         this.unitaryNode = unitaryNode;  
  59.     }  
  60.   
  61.     /** 
  62.      *  解析节点类型 
  63.      * @param value 
  64.      * @return 
  65.      */  
  66.     private static ExpressionNodeType parseNodeType(String value)  
  67.     {  
  68.         if (StringUtils.isEmpty(value)){  
  69.             return ExpressionNodeType.Unknown;  
  70.         }   
  71.         switch (value)  
  72.         {  
  73.             case "+":  
  74.                 return ExpressionNodeType.Plus;  
  75.             case "-":  
  76.                 return ExpressionNodeType.Subtract;  
  77.             case "*":  
  78.                 return ExpressionNodeType.MultiPly;  
  79.             case "/":  
  80.                 return ExpressionNodeType.Divide;  
  81.             case "%":  
  82.                 return ExpressionNodeType.Mod;  
  83.             case "^":  
  84.                 return ExpressionNodeType.Power;  
  85.             case "(":  
  86.                 return ExpressionNodeType.LParentheses;  
  87.             case ")":  
  88.                 return ExpressionNodeType.RParentheses;  
  89.             case "&":  
  90.                 return ExpressionNodeType.BitwiseAnd;  
  91.             case "|":  
  92.                 return ExpressionNodeType.BitwiseOr;  
  93.             case "&&":  
  94.             case "<并且>":  
  95.             case "并且":  
  96.                 return ExpressionNodeType.And;  
  97.             case "||":  
  98.             case "<或者>":  
  99.             case "或者":  
  100.                 return ExpressionNodeType.Or;  
  101.             case "!":  
  102.                 return ExpressionNodeType.Not;  
  103.             case "==":  
  104.             case "=":  
  105.                 return ExpressionNodeType.Equal;  
  106.             case "!=":  
  107.             case "<>":  
  108.             case "≠":  
  109.                 return ExpressionNodeType.Unequal;  
  110.             case ">":  
  111.                 return ExpressionNodeType.GT;  
  112.             case "<":  
  113.                 return ExpressionNodeType.LT;  
  114.             case ">=":  
  115.             case "≥":     
  116.                 return ExpressionNodeType.GTOrEqual;  
  117.             case "<=":  
  118.             case "≤":     
  119.                 return ExpressionNodeType.LTOrEqual;  
  120.             case "<<":  
  121.                 return ExpressionNodeType.LShift;  
  122.             case ">>":  
  123.                 return ExpressionNodeType.RShift;  
  124.             case "@":  
  125.             case "<包含>":  
  126.             case "包含":  
  127.                 return ExpressionNodeType.Like;  
  128.             case "!@":  
  129.             case "<不包含>":  
  130.             case "不包含":  
  131.                 return ExpressionNodeType.NotLike;  
  132.             case "!!$":  
  133.                 return ExpressionNodeType.StartWith;  
  134.             case "!!@":  
  135.                 return ExpressionNodeType.EndWith;  
  136.              
  137.         }  
  138.         if (isNumerics(value))  
  139.         {  
  140.             return ExpressionNodeType.Numeric;  
  141.         }  
  142.         if (isDatetime(value))  
  143.         {  
  144.             return ExpressionNodeType.Date;  
  145.         }  
  146.         if (value.contains("\""))  
  147.         {  
  148.             return ExpressionNodeType.String;  
  149.         }  
  150.         return ExpressionNodeType.Unknown;  
  151.     }  
  152.   
  153.     /** 
  154.      * 获取各节点类型的优先级 
  155.      * @param nodeType 
  156.      * @return 
  157.      */  
  158.     private static int getNodeTypePRI(ExpressionNodeType nodeType)  
  159.     {  
  160.         switch (nodeType)  
  161.         {  
  162.             case LParentheses:  
  163.             case RParentheses:  
  164.                 return 9;  
  165.             //逻辑非是一元操作符,所以其优先级较高  
  166.             case Not:  
  167.                 return 8;  
  168.             case Mod:  
  169.                 return 7;  
  170.             case MultiPly:  
  171.             case Divide:  
  172.             case Power:  
  173.                 return 6;  
  174.             case Plus:  
  175.             case Subtract:  
  176.                 return 5;  
  177.             case LShift:  
  178.             case RShift:  
  179.                 return 4;  
  180.             case BitwiseAnd:  
  181.             case BitwiseOr:  
  182.                 return 3;  
  183.             case Equal:  
  184.             case Unequal:  
  185.             case GT:  
  186.             case LT:  
  187.             case GTOrEqual:  
  188.             case LTOrEqual:  
  189.             case Like:  
  190.             case NotLike:  
  191.             case StartWith:  
  192.             case EndWith:  
  193.                 return 2;  
  194.             case And:  
  195.             case Or:  
  196.                 return 1;  
  197.             default:  
  198.                 return 0;  
  199.         }  
  200.           
  201.     }  
  202.   
  203.     /** 
  204.      * 判断是否为数值 
  205.      * @param op 
  206.      * @return 
  207.      */  
  208.     public static boolean isNumerics(String op)  
  209.     {  
  210.         return op.matches("^[\\+\\-]?(0|[1-9]\\d*|[1-9]\\d*\\.\\d+|0\\.\\d+)");  
  211.     }  
  212.   
  213.     /** 
  214.      * 判断是否为日期 
  215.      * @param op 
  216.      * @return 
  217.      */  
  218.     public static boolean isDatetime(String op)  
  219.     {  
  220.         op = op.replace("\"","").trim();  
  221.         return op.matches("\\d{4}\\-\\d{2}\\-\\d{2}(\\s\\d{2}\\:\\d{2}\\:\\d{2})?");  
  222.     }  
  223.   
  224.       
  225.     /** 
  226.      * 判断某个字符后是否需要更多的操作符 
  227.      * @param c 
  228.      * @return 
  229.      */  
  230.     public static boolean needMoreOperator(char c)  
  231.     {  
  232.         switch (c)  
  233.         {  
  234.             case '&':  
  235.             case '|':  
  236.             case '=':  
  237.             case '!':  
  238.             case '>':  
  239.             case '<':  
  240.             case '.':   //小数点  
  241.                 return true;  
  242.         }  
  243. //        //数字则需要更多  
  244.         return Character.isDigit(c);  
  245.     }  
  246.   
  247.     /** 
  248.      * 判断两个字符是否是同一类 
  249.      * @param c1 
  250.      * @param c2 
  251.      * @return 
  252.      */  
  253.     public static boolean IsCongener(char c1, char c2)  
  254.     {  
  255.          if ((c1 == '(') || (c2 == '(')){  
  256.              return false;  
  257.          }  
  258.          if ((c1 == ')') || (c2 == ')')){  
  259.              return false;  
  260.          }  
  261.          if ((c1 == '"') || (c2 == '"')){  
  262.              return false;  
  263.          }  
  264.          if (Character.isDigit(c1) || (c1 == '.'))  
  265.          {  
  266.             //c1为数字,则c2也为数字  
  267.              return (Character.isDigit(c2) || (c2 == '.'));  
  268.          }  
  269.          return (!Character.isDigit(c2) && (c2 != '.'));  
  270.     }  
  271.   
  272.     /** 
  273.      * 判断某个字符是否是空白字符 
  274.      * @param c 
  275.      * @return 
  276.      */  
  277.     public static boolean IsWhileSpace(char c)  
  278.     {  
  279.         return c == ' ' || c == '\t';  
  280.     }  
  281.   
  282.     /** 
  283.      * 判断是否是一元操作符节点 
  284.      * @param nodeType 
  285.      * @return 
  286.      */  
  287.     public static boolean IsUnitaryNode(ExpressionNodeType nodeType)  
  288.     {  
  289.         return (nodeType == ExpressionNodeType.Plus || nodeType == ExpressionNodeType.Subtract);  
  290.     }  
  291.   
  292.     public String getValue() {  
  293.         return value;  
  294.     }  
  295.   
  296.     public void setValue(String value) {  
  297.         this.value = value;  
  298.     }  
  299.   
  300.     public ExpressionNodeType getType() {  
  301.         return type;  
  302.     }  
  303.   
  304.     public void setType(ExpressionNodeType type) {  
  305.         this.type = type;  
  306.     }  
  307.   
  308.     public int getPri() {  
  309.         return pri;  
  310.     }  
  311.   
  312.     public void setPri(int pri) {  
  313.         this.pri = pri;  
  314.     }  
  315.   
  316.     public ExpressionNode getUnitaryNode() {  
  317.         return unitaryNode;  
  318.     }  


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

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

 

[java] view plain copy
 
 print?
  1. public class ExpressionException extends RuntimeException{  
  2.   
  3.     private static final long serialVersionUID = 1L;  
  4.   
  5.     public ExpressionException() {  
  6.         super();  
  7.     }  
  8.   
  9.     public ExpressionException(String msg) {  
  10.         super(msg);  
  11.     }  
  12.       
  13.     public ExpressionException(String msg, Throwable cause) {  
  14.         super(msg,cause);  
  15.     }  
  16.       
  17.     public ExpressionException(Throwable cause) {  
  18.         super(cause);  
  19.     }  
  20. }  


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

 

 

[java] view plain copy
 
 print?
  1. public class ExpressionParser {  
  2.   
  3.     //当前分析的表达式  
  4.     private String expression;  
  5.       
  6.     //当前读取的位置  
  7.     private int position;  
  8.       
  9.     public String getExpression() {  
  10.         return expression;  
  11.     }  
  12.   
  13.     public void setExpression(String expression) {  
  14.         this.expression = expression;  
  15.     }  
  16.   
  17.     public int getPosition() {  
  18.         return position;  
  19.     }  
  20.   
  21.     public void setPosition(int position) {  
  22.         this.position = position;  
  23.     }  
  24.   
  25.     public ExpressionParser(String expression)  
  26.     {  
  27.         this.expression = expression;  
  28.         this.position = 0;  
  29.     }  
  30.   
  31.     /** 
  32.      *  读取下一个表达式节点,如果读取失败则返回null 
  33.      * @return 
  34.      */  
  35.     public ExpressionNode readNode()  
  36.     {  
  37.         //空格的位置  
  38.         int whileSpacePos = -1;  
  39.         boolean flag = false;  
  40.         StringBuffer buffer = new StringBuffer(10);  
  41.         while (this.position < this.expression.length())  
  42.         {  
  43.             char c = this.expression.charAt(this.position);  
  44.             if (c == '"')  
  45.             {  
  46.                 flag = !flag;  
  47.                 if (!flag)  
  48.                 {  
  49.                     this.position++;  
  50.                     buffer.append(c);  
  51.                     break;  
  52.                 }  
  53.                 if (buffer.length() != 0)  
  54.                 {  
  55.                     break;  
  56.                 }  
  57.             }  
  58.             if (flag)  
  59.             {  
  60.                 this.position++;  
  61.                 buffer.append(c);  
  62.             }  
  63.             else  
  64.             {  
  65.                 if (ExpressionNode.IsWhileSpace(c))  
  66.                 {  
  67.                     if ((whileSpacePos >= 0) && ((this.position - whileSpacePos) > 1))  
  68.                     {  
  69.                         throw new ExpressionException(String.format("表达式\"%s\"在位置(%s)上的字符非法!", this.getExpression(), this.getPosition()));  
  70.                     }  
  71.                     if (buffer.length() == 0)  
  72.                     {  
  73.                         whileSpacePos = -1;  
  74.                     }  
  75.                     else  
  76.                     {  
  77.                         whileSpacePos = this.position;  
  78.                     }  
  79.                     this.position++;  
  80.                     continue;  
  81.                 }  
  82.                 if ((buffer.length() == 0) || ExpressionNode.IsCongener(c, buffer.charAt(buffer.length() - 1)))  
  83.                 {  
  84.                     this.position++;  
  85.                     buffer.append(c);  
  86.                 }  
  87.                 else  
  88.                 {  
  89.                     break;  
  90.                 }  
  91.                 if (!ExpressionNode.needMoreOperator(c))  
  92.                 {  
  93.                     break;  
  94.                 }  
  95.             }  
  96.         }  
  97.         if (buffer.length() == 0)  
  98.         {  
  99.             return null;  
  100.         }  
  101.         ExpressionNode node = new ExpressionNode(buffer.toString());  
  102.         if (node.getType() == ExpressionNodeType.Unknown)  
  103.         {  
  104.             throw new ExpressionException(String.format("表达式\"%s\"在位置%s上的字符\"%s\"非法!", this.getExpression(), this.getPosition() - node.getValue().length(), node.getValue()));  
  105.         }  
  106.         return node;  
  107.     }  
  108.       
  109. }  


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

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

 

[java] view plain copy
 
 print?
  1. public class ExpressionEvaluator {  
  2.   
  3.      private ExpressionEvaluator()  
  4.      {  
  5.            
  6.      }  
  7.       
  8.      /** 
  9.       * 将算术表达式转换为逆波兰表达式 
  10.       * @param expression 要计算的表达式,如"1+2+3+4" 
  11.       * @return 
  12.       */  
  13.      private static List<ExpressionNode> parseExpression(String expression)  
  14.      {  
  15.          if(StringUtils.isEmpty(expression)){  
  16.              return new ArrayList<ExpressionNode>();  
  17.          }  
  18.   
  19.          List<ExpressionNode> listOperator = new ArrayList<ExpressionNode>(10);  
  20.          Stack<ExpressionNode> stackOperator = new Stack<ExpressionNode>();  
  21.   
  22.          ExpressionParser expParser = new ExpressionParser(expression);  
  23.          ExpressionNode beforeExpNode = null;       //前一个节点              
  24.          ExpressionNode unitaryNode = null;         //一元操作符  
  25.          ExpressionNode expNode;  
  26.   
  27.          //是否需要操作数  
  28.          boolean requireOperand = false;  
  29.   
  30.   
  31.          while ((expNode = expParser.readNode()) != null)  
  32.          {  
  33.              if ( (expNode.getType() == ExpressionNodeType.Numeric) ||   
  34.                      (expNode.getType() == ExpressionNodeType.String) ||   
  35.                      (expNode.getType() == ExpressionNodeType.Date))  
  36.              {  
  37.                  //操作数, 直接加入后缀表达式中  
  38.                  if (unitaryNode != null)  
  39.                  {  
  40.                      //设置一元操作符节点  
  41.                      expNode.setUnitaryNode(unitaryNode);  
  42.                      unitaryNode = null;  
  43.                  }  
  44.   
  45.                  listOperator.add(expNode);  
  46.                  requireOperand = false;  
  47.                  continue;  
  48.              }  
  49.              else if (expNode.getType() == ExpressionNodeType.LParentheses)  
  50.              {  
  51.                  //左括号, 直接加入操作符栈  
  52.                  stackOperator.push(expNode);  
  53.                  continue;  
  54.              }  
  55.              else if (expNode.getType() == ExpressionNodeType.RParentheses)  
  56.              {  
  57.                  //右括号则在操作符栈中反向搜索,直到遇到匹配的左括号为止,将中间的操作符依次加到后缀表达式中。  
  58.                  ExpressionNode lpNode = null;  
  59.                  while (stackOperator.size() > 0)  
  60.                  {  
  61.                      lpNode = stackOperator.pop();  
  62.                      if (lpNode.getType() == ExpressionNodeType.LParentheses) break;  
  63.                      listOperator.add(lpNode);  
  64.                  }  
  65.                  if (lpNode == null || lpNode.getType() != ExpressionNodeType.LParentheses)  
  66.                  {  
  67.                      throw new ExpressionException(String.format("在表达式\"%s\"中没有与在位置(%s)上\")\"匹配的\"(%s)\"字符!", expParser.getExpression(), expParser.getPosition()));  
  68.                  }  
  69.              }  
  70.              else  
  71.              {  
  72.                  if (stackOperator.size() == 0)  
  73.                  {  
  74.                      //第一个节点则判断此节点是否是一元操作符"+,-,!,("中的一个,否则其它都非法  
  75.                      if (listOperator.size() == 0 &&  
  76.                          !(expNode.getType() == ExpressionNodeType.LParentheses || expNode.getType() == ExpressionNodeType.Not))  
  77.                      {  
  78.                          //后缀表达式没有任何数据则判断是否是一元操作数  
  79.                          if (ExpressionNode.IsUnitaryNode(expNode.getType()))  
  80.                          {  
  81.                              unitaryNode = expNode;  
  82.                          }  
  83.                          else  
  84.                          {  
  85.                              //丢失操作数  
  86.                              throw new ExpressionException(String.format("表达式\"%s\"在位置(%s)上缺少操作数!", expParser.getExpression(), expParser.getPosition()));  
  87.                          }  
  88.                      }  
  89.                      else  
  90.                      {  
  91.                          //直接压入操作符栈  
  92.                          stackOperator.push(expNode);  
  93.                      }  
  94.                      requireOperand = true;          //下一个节点需要操作数  
  95.                      continue;  
  96.                  }  
  97.                  else  
  98.                  {  
  99.                      if (requireOperand)  
  100.                      {  
  101.                          //如果需要操作数则判断当前的是否是"+","-"号(一元操作符),如果是则继续  
  102.                          if (ExpressionNode.IsUnitaryNode(expNode.getType()) && unitaryNode == null)  
  103.                          {  
  104.                              unitaryNode = expNode;  
  105.                          }  
  106.                          else  
  107.                          {  
  108.                              //丢失操作数  
  109.                              throw new ExpressionException(String.format("表达式\"%s\"在位置({1})上缺少操作数!", expParser.getExpression(), expParser.getPosition()));  
  110.                          }  
  111.                      }  
  112.                      else  
  113.                      {  
  114.                          //对前面的所有操作符进行优先级比较  
  115.                          do  
  116.                          {  
  117.                              //取得上一次的操作符  
  118.                              beforeExpNode = stackOperator.peek();  
  119.   
  120.                              //如果前一个操作符优先级较高,则将前一个操作符加入后缀表达式中  
  121.                              if (beforeExpNode.getType() != ExpressionNodeType.LParentheses && (beforeExpNode.getPri() - expNode.getPri()) >= 0)  
  122.                              {  
  123.                                  listOperator.add(stackOperator.pop());  
  124.                              }  
  125.                              else  
  126.                              {  
  127.                                  break;  
  128.                              }  
  129.   
  130.                          } while (stackOperator.size() > 0);  
  131.   
  132.                          //将操作符压入操作符栈  
  133.                          stackOperator.push(expNode);  
  134.                          requireOperand = true;  
  135.                      }  
  136.                  }  
  137.              }  
  138.          }  
  139.   
  140.          if (requireOperand)  
  141.          {  
  142.              //丢失操作数  
  143.              throw new ExpressionException(String.format("表达式\"%s\"在位置({1})上缺少操作数!", expParser.getExpression(), expParser.getPosition()));  
  144.          }  
  145.          //清空堆栈  
  146.          while (stackOperator.size() > 0)  
  147.          {  
  148.              //取得操作符  
  149.              beforeExpNode = stackOperator.pop();  
  150.              if (beforeExpNode.getType() == ExpressionNodeType.LParentheses)  
  151.              {  
  152.                  throw new ExpressionException(String.format("表达式\"%s\"中括号不匹配,丢失右括号!", expParser.getExpression(), expParser.getPosition()));  
  153.              }  
  154.              listOperator.add(beforeExpNode);  
  155.          }  
  156.   
  157.          return listOperator;  
  158.      }  
  159.       
  160.      /** 
  161.       * 对逆波兰表达式进行计算 
  162.       * @param nodes 
  163.       * @return 
  164.       */  
  165.      private static Object CalcExpression(List<ExpressionNode> nodes)  
  166.      {  
  167.          if (nodes == null || nodes.size() == 0) return null;  
  168.   
  169.          if (nodes.size() > 1)  
  170.          {  
  171.              int index = 0;  
  172.              //储存数据  
  173.              ArrayList values = new ArrayList();  
  174.              while (index < nodes.size())  
  175.              {  
  176.                  ExpressionNode node = nodes.get(index);  
  177.                           
  178.                  switch (node.getType())  
  179.                  {  
  180.                      //如果是数字,则将值存入 values 中  
  181.                      case Numeric:  
  182.                      case String:  
  183.                      case Date:  
  184.                          values.add(node.getNumeric());  
  185.                          index++;  
  186.                          break;  
  187.                      default:     
  188.                          //二元表达式,需要二个参数, 如果是Not的话,则只要一个参数  
  189.                          int paramCount = 2;  
  190.                          if (node.getType() == ExpressionNodeType.Not) paramCount = 1;  
  191.                          //计算操作数的值  
  192.                          if (values.size() < paramCount)  
  193.                          {  
  194.                              throw new ExpressionException("缺少操作数");  
  195.                          }  
  196.                          //传入参数  
  197.                          Object[] data = new Object[paramCount];  
  198.                          for (int i = 0; i < paramCount; i++)  
  199.                          {  
  200.                              data[i] = values.get(index - paramCount + i);  
  201.                          }  
  202.                          //将计算结果再存入当前节点  
  203.                          node.setNumeric(calculate(node.getType(), data));  
  204.                          node.setType( ExpressionNodeType.Numeric);  
  205.                          //将操作数节点删除  
  206.                          for (int i = 0; i < paramCount; i++)  
  207.                          {  
  208.                              nodes.remove(index - i - 1);  
  209.                              values.remove(index - i - 1);  
  210.                          }  
  211.                          index -= paramCount;  
  212.                          break;  
  213.                  }  
  214.                    
  215.              }  
  216.          }  
  217.   
  218.          if (nodes.size() != 1)  
  219.          {  
  220.              throw new ExpressionException("缺少操作符或操作数");  
  221.          }  
  222.          switch (nodes.get(0).getType())  
  223.          {  
  224.              case Numeric:  
  225.                  return nodes.get(0).getNumeric();  
  226.   
  227.              case String:  
  228.              case Date:  
  229.                  return nodes.get(0).getNumeric().toString().replace("\"", "");  
  230.          }  
  231.          throw new ExpressionException("缺少操作数");  
  232.      }  
  233.        
  234.      /** 
  235.       * 计算节点的值 
  236.       * @param nodeType 节点的类型 
  237.       * @param data 要计算的值,有可能是两位或一位数 
  238.       * @return 
  239.       */  
  240.      private static Object calculate(ExpressionNodeType nodeType, Object[] data)  
  241.      {  
  242.          double d1, d2;  
  243.          boolean  b1, b2;  
  244.          Date time1,time2;  
  245.          Object obj1 = data[0];  
  246.          Object obj2 = data[1];  
  247.          String str1 = obj1.toString();  
  248.          String str2 = obj2.toString();  
  249.            
  250.          boolean dateflag = ExpressionNode.isDatetime(str1) || ExpressionNode.isDatetime(str2);  
  251.          boolean strflag = str1.contains("\"") || str2.contains("\"");  
  252.          str1 = str1.replace("\"", "");  
  253.          str2 = str2.replace("\"", "");  
  254.            
  255.          switch (nodeType)  
  256.          {  
  257.              case Plus:  
  258.                  if (!strflag)  
  259.                  {  
  260.                      d1 = ConvertToDecimal(obj1);  
  261.                      d2 = ConvertToDecimal(obj2);  
  262.                      return (d1 + d2);  
  263.                  }  
  264.                  return new StringBuffer(str1 + str2).toString();  
  265.              case Subtract:  
  266.                  d1 = ConvertToDecimal(obj1);  
  267.                  d2 = ConvertToDecimal(obj2);  
  268.                  return d1 - d2;  
  269.              case MultiPly:  
  270.                  d1 = ConvertToDecimal(obj1);  
  271.                  d2 = ConvertToDecimal(obj2);  
  272.                  return d1 * d2;  
  273.              case Divide:  
  274.                  d1 = ConvertToDecimal(obj1);  
  275.                  d2 = ConvertToDecimal(obj2);  
  276.                  if (d2 == 0)throw new RuntimeException();  
  277.                  return d1 / d2;  
  278.              case Power:  
  279.                  d1 = ConvertToDecimal(obj1);  
  280.                  d2 = ConvertToDecimal(obj2);  
  281.                  return Math.pow((double)d1, (double)d2);  
  282.              case Mod:  
  283.                  d1 = ConvertToDecimal(obj1);  
  284.                  d2 = ConvertToDecimal(obj2);  
  285.                  if (d2 == 0) throw new RuntimeException();  
  286.                  return d1 % d2;  
  287.              case BitwiseAnd:  
  288.                  d1 = ConvertToDecimal(obj1);  
  289.                  d2 = ConvertToDecimal(obj2);  
  290.                  return (int)d1 & (int)d2;  
  291.              case BitwiseOr:  
  292.                  d1 = ConvertToDecimal(obj1);  
  293.                  d2 = ConvertToDecimal(obj2);  
  294.                  return (int)d1 | (int)d2;  
  295.              case And:  
  296.                  b1 = ConvertToBool(obj1);  
  297.                  b2 = ConvertToBool(obj2);  
  298.                  return b1 && b2;  
  299.              case Or:  
  300.                  b1 = ConvertToBool(obj1);  
  301.                  b2 = ConvertToBool(obj2);  
  302.                  return b1 || b2;  
  303.              case Not:  
  304.                  b1 = ConvertToBool(obj1);  
  305.                  return !b1;  
  306.              case Equal:  
  307.                  if (!dateflag)  
  308.                  {  
  309.                      if (strflag)  
  310.                      {  
  311.                          return str1.equals(str2);  
  312.                      }  
  313.                      d1 = ConvertToDecimal(obj1);  
  314.                      d2 = ConvertToDecimal(obj2);  
  315.                      return (d1 == d2);  
  316.                  }  
  317.                  time1 = DateUtils.parse(str1);  
  318.                  time2 = DateUtils.parse(str2);  
  319.                    
  320.                  return (time1.getTime() == time2.getTime());  
  321.              case Unequal:  
  322.                  if (!dateflag)  
  323.                  {  
  324.                      if (strflag)  
  325.                      {  
  326.                          return (!str1.equals(str2));  
  327.                      }  
  328.                      d1 = ConvertToDecimal(obj1);  
  329.                      d2 = ConvertToDecimal(obj2);  
  330.                      return (d1 != d2);  
  331.                  }  
  332.                  time1 = DateUtils.parse(str1);  
  333.                  time2 = DateUtils.parse(str2);  
  334.                    
  335.                  return (time1.getTime() != time2.getTime());  
  336.              case GT:  
  337.                    
  338.                  if (!dateflag)  
  339.                  {  
  340.                      d1 = ConvertToDecimal(obj1);  
  341.                      d2 = ConvertToDecimal(obj2);  
  342.                      return (d1 > d2);  
  343.                  }  
  344.                  time1 = DateUtils.parse(str1);  
  345.                  time2 = DateUtils.parse(str2);  
  346.                  return (time1.getTime() > time2.getTime());  
  347.                    
  348.              case LT:  
  349.                    
  350.                  if (!dateflag)  
  351.                  {  
  352.                      d1 = ConvertToDecimal(obj1);  
  353.                      d2 = ConvertToDecimal(obj2);  
  354.                      return (d1 < d2);  
  355.                  }  
  356.                  time1 = DateUtils.parse(str1);  
  357.                  time2 = DateUtils.parse(str2);  
  358.                  return (time1.getTime() < time2.getTime());  
  359.                    
  360.              case GTOrEqual:  
  361.                    
  362.                  if (!dateflag)  
  363.                  {  
  364.                      d1 = ConvertToDecimal(obj1);  
  365.                      d2 = ConvertToDecimal(obj2);  
  366.                      return (d1 >= d2);  
  367.                  }  
  368.                  time1 = DateUtils.parse(str1);  
  369.                  time2 = DateUtils.parse(str2);  
  370.                  return (time1.getTime() >= time2.getTime());  
  371.                    
  372.              case LTOrEqual:  
  373.                  if (!dateflag)  
  374.                  {  
  375.                      d1 = ConvertToDecimal(obj1);  
  376.                      d2 = ConvertToDecimal(obj2);  
  377.                      return (d1 <= d2);  
  378.                  }  
  379.                  time1 = DateUtils.parse(str1);  
  380.                  time2 = DateUtils.parse(str2);  
  381.                  return (time1.getTime() <= time2.getTime());  
  382.              case LShift:  
  383.                  d1 = ConvertToDecimal(obj1);  
  384.                  d2 = ConvertToDecimal(obj2);  
  385.                  return (long)d1 << (int)d2;  
  386.                    
  387.              case RShift:  
  388.                  d1 = ConvertToDecimal(obj1);  
  389.                  d2 = ConvertToDecimal(obj2);  
  390.                  return (long)d1 >> (int)d2;  
  391.              case Like:  
  392.                  if (!strflag)  
  393.                  {  
  394.                      return false;  
  395.                  }  
  396.                  return str1.contains(str2);  
  397.              case NotLike:  
  398.                  if (!strflag)  
  399.                  {  
  400.                      return false;  
  401.                  }  
  402.                  return !str1.contains(str2);  
  403.              case StartWith:  
  404.                  if (!strflag)  
  405.                  {  
  406.                      return false;  
  407.                  }  
  408.                  return str1.startsWith(str2);  
  409.              case EndWith:  
  410.                  if (!strflag)  
  411.                  {  
  412.                      return false;  
  413.                  }  
  414.                  return str1.endsWith(str2);        
  415.          }  
  416.            
  417.          return 0;  
  418.      }  
  419.       
  420.      /** 
  421.       * 某个值转换为bool值 
  422.       * @param value 
  423.       * @return 
  424.       */  
  425.      private static Boolean ConvertToBool(Object value)  
  426.      {  
  427.          if (value instanceof Boolean){  
  428.              return (Boolean)value;  
  429.          }  
  430.          else{  
  431.              return value != null;  
  432.          }  
  433.      }  
  434.   
  435.      /** 
  436.       * 将某个值转换为decimal值 
  437.       * @param value 
  438.       * @return 
  439.       */  
  440.      private static Double ConvertToDecimal(Object value)  
  441.      {  
  442.          if (value instanceof Boolean)  
  443.          {  
  444.              return ((Boolean)value ? 1d : 0d);  
  445.          }  
  446.          else  
  447.          {  
  448.              return Double.parseDouble(value.toString());  
  449.          }  
  450.      }  
  451.       
  452.      /** 
  453.       *  
  454.       * @param expression 要计算的表达式,如"1+2+3+4" 
  455.       * @return 返回计算结果,如果带有逻辑运算符则返回true/false,否则返回数值 
  456.       */  
  457.      public static Object eval(String expression)  
  458.      {  
  459.          return CalcExpression(parseExpression(expression));  
  460.      }  
  461.        
  462.      public static Object evalThreeOperand(String expression)  
  463.      {  
  464.          int index = expression.indexOf("?");  
  465.          if (index > -1)  
  466.          {  
  467.              String str = expression.substring(0, index);  
  468.              String str2 = expression.substring(index + 1);  
  469.              index = str2.indexOf(":");  
  470.               
  471.              if ( Boolean.parseBoolean((CalcExpression(parseExpression(str))).toString()))  
  472.              {  
  473.                  return eval(str2.substring(0, index));  
  474.              }  
  475.              return eval(str2.substring(index + 1));  
  476.          }  
  477.          return CalcExpression(parseExpression(expression));  
  478.      }  
  479.        
  480. }  


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

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

posted on 2017-09-30 14:27  csguo  阅读(4855)  评论(1编辑  收藏  举报