因项目需要,在网上找来一套表达式解析方法,由于原来的方法太过于零散,不利于移植,现在整理在同一文件内;

文件中包含5个内部类,源码如下:

   1 import java.util.ArrayList;
   2 import java.util.Date;
   3 import java.util.List;
   4 import java.util.Stack;
   5
   6 /**
   7  * @项目名称: sunson_pams
   8  * @类名称: FormulaUtils
   9  * @类描述: 非原创(慎用)
  10  * @创建人: 唐泽齐
  11  * @创建时间: 2017年12月15日 上午9:47:23
  12  * @修改人: 唐泽齐
  13  * @修改时间: 2017年12月15日 上午9:47:23
  14  * @修改备注:
  15  * @version: 1.0
  16  */
  17 public class FormulaUtils {
  18
  19     /**
  20      * 表达式解析
  21      */
  22     public static ExpressionEvaluator ExpressionEvaluator;
  23
  24     public FormulaUtils() {
  25         ExpressionEvaluator = new ExpressionEvaluator();
  26     };
  27
  28     /**
  29      * 表达式各个字符节点的类型枚举类
  30      *
  31      * @项目名称: sunson_pams
  32      * @类名称: ExpressionNodeType
  33      * @类描述:
  34      * @创建人: 唐泽齐
  35      * @创建时间: 2017年12月15日 上午9:49:48
  36      * @修改人: 唐泽齐
  37      * @修改时间: 2017年12月15日 上午9:49:48
  38      * @修改备注:
  39      * @version: 1.0
  40      */
  41     public enum ExpressionNodeType {
  42
  43         Unknown, Plus, // +
  44         Subtract, /// -
  45         MultiPly, // *
  46         Divide, // /
  47         LParentheses, // (
  48         RParentheses, /// )
  49         Mod, // % (求模,取余)
  50         Power, // ^ (次幂)
  51         BitwiseAnd, /// & (按位与)
  52         BitwiseOr, /// | (按位或)
  53         And, // && (逻辑与)
  54         Or, /// || (逻辑或)
  55         Not, /// ! (逻辑非)
  56         Equal, /// == (相等)
  57         Unequal, /// != 或 <> (不等于)
  58         GT, /// > (大于)
  59         LT, /// < (小于)
  60         GTOrEqual, /// >= (大于等于)
  61         LTOrEqual, /// <= (小于等于)
  62         LShift, /// << (左移位)
  63         RShift, /// >> (右移位)
  64         Numeric, /// 数值,
  65         String, Date, Like, // 包含
  66         NotLike, // 不包含
  67         StartWith, // 已什么开始
  68         EndWith// 已什么结尾
  69
  70     }
  71
  72     /**
  73      * 存储表达式运算符或操作数的各个节点的类
  74      *
  75      * @项目名称: sunson_pams
  76      * @类名称: ExpressionNode
  77      * @类描述:
  78      * @创建人: 唐泽齐
  79      * @创建时间: 2017年12月15日 上午9:50:50
  80      * @修改人: 唐泽齐
  81      * @修改时间: 2017年12月15日 上午9:50:50
  82      * @修改备注:
  83      * @version: 1.0
  84      */
  85     public static class ExpressionNode {
  86
  87         private String value;
  88
  89         private ExpressionNodeType type;
  90
  91         private int pri;
  92
  93         private ExpressionNode unitaryNode;
  94
  95         private Object numeric;
  96
  97         /**
  98          *
  99          * @param value
 100          *            操作数或运算符
 101          */
 102         public ExpressionNode(String value) {
 103             this.value = value;
 104             this.type = parseNodeType(value);
 105             this.pri = getNodeTypePRI(this.type);
 106             this.numeric = null;
 107         }
 108
 109         public Object getNumeric() {
 110             if (this.numeric == null) {
 111
 112                 if ((this.type == ExpressionNodeType.String) || (this.type == ExpressionNodeType.Date)) {
 113                     return this.value;
 114                 }
 115
 116                 if (this.type != ExpressionNodeType.Numeric) {
 117                     return 0;
 118                 }
 119                 Double num = new Double(this.value);
 120                 if (this.unitaryNode != null && this.unitaryNode.type == ExpressionNodeType.Subtract) {
 121                     num = 0 - num;
 122                 }
 123                 this.numeric = num;
 124             }
 125             return numeric;
 126         }
 127
 128         public void setNumeric(Object numeric) {
 129             this.numeric = numeric;
 130             this.value = this.numeric.toString();
 131         }
 132
 133         /**
 134          * 设置或返回与当前节点相关联的一元操作符节点
 135          *
 136          * @param unitaryNode
 137          */
 138         public void setUnitaryNode(ExpressionNode unitaryNode) {
 139             this.unitaryNode = unitaryNode;
 140         }
 141
 142         /**
 143          * 解析节点类型
 144          *
 145          * @param value
 146          * @return
 147          */
 148         private ExpressionNodeType parseNodeType(String value) {
 149             if (StringUtils.isEmpty(value)) {
 150                 return ExpressionNodeType.Unknown;
 151             }
 152             switch (value) {
 153             case "+":
 154                 return ExpressionNodeType.Plus;
 155             case "-":
 156                 return ExpressionNodeType.Subtract;
 157             case "*":
 158                 return ExpressionNodeType.MultiPly;
 159             case "/":
 160                 return ExpressionNodeType.Divide;
 161             case "%":
 162                 return ExpressionNodeType.Mod;
 163             case "^":
 164                 return ExpressionNodeType.Power;
 165             case "(":
 166                 return ExpressionNodeType.LParentheses;
 167             case ")":
 168                 return ExpressionNodeType.RParentheses;
 169             case "&":
 170                 return ExpressionNodeType.BitwiseAnd;
 171             case "|":
 172                 return ExpressionNodeType.BitwiseOr;
 173             case "&&":
 174             case "<并且>":
 175             case "并且":
 176                 return ExpressionNodeType.And;
 177             case "||":
 178             case "<或者>":
 179             case "或者":
 180                 return ExpressionNodeType.Or;
 181             case "!":
 182                 return ExpressionNodeType.Not;
 183             case "==":
 184             case "=":
 185                 return ExpressionNodeType.Equal;
 186             case "!=":
 187             case "<>":
 188             case "≠":
 189                 return ExpressionNodeType.Unequal;
 190             case ">":
 191                 return ExpressionNodeType.GT;
 192             case "<":
 193                 return ExpressionNodeType.LT;
 194             case ">=":
 195             case "≥":
 196                 return ExpressionNodeType.GTOrEqual;
 197             case "<=":
 198             case "≤":
 199                 return ExpressionNodeType.LTOrEqual;
 200             case "<<":
 201                 return ExpressionNodeType.LShift;
 202             case ">>":
 203                 return ExpressionNodeType.RShift;
 204             case "@":
 205             case "<包含>":
 206             case "包含":
 207                 return ExpressionNodeType.Like;
 208             case "!@":
 209             case "<不包含>":
 210             case "不包含":
 211                 return ExpressionNodeType.NotLike;
 212             case "!!$":
 213                 return ExpressionNodeType.StartWith;
 214             case "!!@":
 215                 return ExpressionNodeType.EndWith;
 216
 217             }
 218             if (isNumerics(value)) {
 219                 return ExpressionNodeType.Numeric;
 220             }
 221             if (isDatetime(value)) {
 222                 return ExpressionNodeType.Date;
 223             }
 224             if (value.contains("\"")) {
 225                 return ExpressionNodeType.String;
 226             }
 227             return ExpressionNodeType.Unknown;
 228         }
 229
 230         /**
 231          * 获取各节点类型的优先级
 232          *
 233          * @param nodeType
 234          * @return
 235          */
 236         private int getNodeTypePRI(ExpressionNodeType nodeType) {
 237             switch (nodeType) {
 238             case LParentheses:
 239             case RParentheses:
 240                 return 9;
 241             // 逻辑非是一元操作符,所以其优先级较高
 242             case Not:
 243                 return 8;
 244             case Mod:
 245                 return 7;
 246             case MultiPly:
 247             case Divide:
 248             case Power:
 249                 return 6;
 250             case Plus:
 251             case Subtract:
 252                 return 5;
 253             case LShift:
 254             case RShift:
 255                 return 4;
 256             case BitwiseAnd:
 257             case BitwiseOr:
 258                 return 3;
 259             case Equal:
 260             case Unequal:
 261             case GT:
 262             case LT:
 263             case GTOrEqual:
 264             case LTOrEqual:
 265             case Like:
 266             case NotLike:
 267             case StartWith:
 268             case EndWith:
 269                 return 2;
 270             case And:
 271             case Or:
 272                 return 1;
 273             default:
 274                 return 0;
 275             }
 276
 277         }
 278
 279         /**
 280          * 判断是否为数值
 281          *
 282          * @param op
 283          * @return
 284          */
 285         public boolean isNumerics(String op) {
 286             return op.matches("^[\\+\\-]?(0|[1-9]\\d*|[1-9]\\d*\\.\\d+|0\\.\\d+)");
 287         }
 288
 289         /**
 290          * 判断是否为日期
 291          *
 292          * @param op
 293          * @return
 294          */
 295         public static boolean isDatetime(String op) {
 296             op = op.replace("\"", "").trim();
 297             return op.matches("\\d{4}\\-\\d{2}\\-\\d{2}(\\s\\d{2}\\:\\d{2}\\:\\d{2})?");
 298         }
 299
 300         /**
 301          * 判断某个字符后是否需要更多的操作符
 302          *
 303          * @param c
 304          * @return
 305          */
 306         public boolean needMoreOperator(char c) {
 307             switch (c) {
 308             case '&':
 309             case '|':
 310             case '=':
 311             case '!':
 312             case '>':
 313             case '<':
 314             case '.': // 小数点
 315                 return true;
 316             }
 317             // //数字则需要更多
 318             return Character.isDigit(c);
 319         }
 320
 321         /**
 322          * 判断两个字符是否是同一类
 323          *
 324          * @param c1
 325          * @param c2
 326          * @return
 327          */
 328         public boolean IsCongener(char c1, char c2) {
 329             if ((c1 == '(') || (c2 == '(')) {
 330                 return false;
 331             }
 332             if ((c1 == ')') || (c2 == ')')) {
 333                 return false;
 334             }
 335             if ((c1 == '"') || (c2 == '"')) {
 336                 return false;
 337             }
 338             if (Character.isDigit(c1) || (c1 == '.')) {
 339                 // c1为数字,则c2也为数字
 340                 return (Character.isDigit(c2) || (c2 == '.'));
 341             }
 342             return (!Character.isDigit(c2) && (c2 != '.'));
 343         }
 344
 345         /**
 346          * 判断某个字符是否是空白字符
 347          *
 348          * @param c
 349          * @return
 350          */
 351         public boolean IsWhileSpace(char c) {
 352             return c == ' ' || c == '\t';
 353         }
 354
 355         /**
 356          * 判断是否是一元操作符节点
 357          *
 358          * @param nodeType
 359          * @return
 360          */
 361         public static boolean IsUnitaryNode(ExpressionNodeType nodeType) {
 362             return (nodeType == ExpressionNodeType.Plus || nodeType == ExpressionNodeType.Subtract);
 363         }
 364
 365         public String getValue() {
 366             return value;
 367         }
 368
 369         public void setValue(String value) {
 370             this.value = value;
 371         }
 372
 373         public ExpressionNodeType getType() {
 374             return type;
 375         }
 376
 377         public void setType(ExpressionNodeType type) {
 378             this.type = type;
 379         }
 380
 381         public int getPri() {
 382             return pri;
 383         }
 384
 385         public void setPri(int pri) {
 386             this.pri = pri;
 387         }
 388
 389         public ExpressionNode getUnitaryNode() {
 390             return unitaryNode;
 391         }
 392     }
 393
 394     /**
 395      * 表达式异常类
 396      *
 397      * @项目名称: sunson_pams
 398      * @类名称: ExpressionException
 399      * @类描述:
 400      * @创建人: 唐泽齐
 401      * @创建时间: 2017年12月15日 上午9:52:13
 402      * @修改人: 唐泽齐
 403      * @修改时间: 2017年12月15日 上午9:52:13
 404      * @修改备注:
 405      * @version: 1.0
 406      */
 407     public static class ExpressionException extends RuntimeException {
 408
 409         /**
 410          *
 411          */
 412         private static final long serialVersionUID = 3136681292988750961L;
 413
 414         public ExpressionException() {
 415             super();
 416         }
 417
 418         public ExpressionException(String msg) {
 419             super(msg);
 420         }
 421
 422         public ExpressionException(String msg, Throwable cause) {
 423             super(msg, cause);
 424         }
 425
 426         public ExpressionException(Throwable cause) {
 427             super(cause);
 428         }
 429     }
 430
 431     /**
 432      * 负责读取表达式生成ExpressionNode对象的类
 433      *
 434      * @项目名称: sunson_pams
 435      * @类名称: ExpressionParser
 436      * @类描述:
 437      * @创建人: 唐泽齐
 438      * @创建时间: 2017年12月15日 上午9:52:59
 439      * @修改人: 唐泽齐
 440      * @修改时间: 2017年12月15日 上午9:52:59
 441      * @修改备注:
 442      * @version: 1.0
 443      */
 444     public static class ExpressionParser {
 445
 446         // 当前分析的表达式
 447         private String expression;
 448
 449         // 当前读取的位置
 450         private int position;
 451
 452         public String getExpression() {
 453             return expression;
 454         }
 455
 456         public void setExpression(String expression) {
 457             this.expression = expression;
 458         }
 459
 460         public int getPosition() {
 461             return position;
 462         }
 463
 464         public void setPosition(int position) {
 465             this.position = position;
 466         }
 467
 468         public ExpressionParser(String expression) {
 469             this.expression = expression;
 470             this.position = 0;
 471         }
 472
 473         /**
 474          * 读取下一个表达式节点,如果读取失败则返回null
 475          *
 476          * @return
 477          */
 478         public ExpressionNode readNode() {
 479             ExpressionNode s = new ExpressionNode(null);
 480             // 空格的位置
 481             int whileSpacePos = -1;
 482             boolean flag = false;
 483             StringBuffer buffer = new StringBuffer(10);
 484             while (this.position < this.expression.length()) {
 485                 char c = this.expression.charAt(this.position);
 486                 if (c == '"') {
 487                     flag = !flag;
 488                     if (!flag) {
 489                         this.position++;
 490                         buffer.append(c);
 491                         break;
 492                     }
 493                     if (buffer.length() != 0) {
 494                         break;
 495                     }
 496                 }
 497                 if (flag) {
 498                     this.position++;
 499                     buffer.append(c);
 500                 } else {
 501                     if (s.IsWhileSpace(c)) {
 502                         if ((whileSpacePos >= 0) && ((this.position - whileSpacePos) > 1)) {
 503                             throw new ExpressionException(
 504                                     String.format("表达式\"%s\"在位置(%s)上的字符非法!", this.getExpression(), this.getPosition()));
 505                         }
 506                         if (buffer.length() == 0) {
 507                             whileSpacePos = -1;
 508                         } else {
 509                             whileSpacePos = this.position;
 510                         }
 511                         this.position++;
 512                         continue;
 513                     }
 514                     if ((buffer.length() == 0) || s.IsCongener(c, buffer.charAt(buffer.length() - 1))) {
 515                         this.position++;
 516                         buffer.append(c);
 517                     } else {
 518                         break;
 519                     }
 520                     if (!s.needMoreOperator(c)) {
 521                         break;
 522                     }
 523                 }
 524             }
 525             if (buffer.length() == 0) {
 526                 return null;
 527             }
 528             ExpressionNode node = new ExpressionNode(buffer.toString());
 529             if (node.getType() == ExpressionNodeType.Unknown) {
 530                 throw new ExpressionException(String.format("表达式\"%s\"在位置%s上的字符\"%s\"非法!", this.getExpression(),
 531                         this.getPosition() - node.getValue().length(), node.getValue()));
 532             }
 533             return node;
 534         }
 535
 536     }
 537
 538     /**
 539      * 解析公式并返回结果的类
 540      *
 541      * @项目名称: sunson_pams
 542      * @类名称: ExpressionEvaluator
 543      * @类描述:
 544      * @创建人: 唐泽齐
 545      * @创建时间: 2017年12月15日 上午9:56:08
 546      * @修改人: 唐泽齐
 547      * @修改时间: 2017年12月15日 上午9:56:08
 548      * @修改备注:
 549      * @version: 1.0
 550      */
 551     public static class ExpressionEvaluator {
 552
 553         private ExpressionEvaluator() {
 554
 555         }
 556
 557         /**
 558          * 将算术表达式转换为逆波兰表达式
 559          *
 560          * @param expression
 561          *            要计算的表达式,如"1+2+3+4"
 562          * @return
 563          */
 564         private static  List<ExpressionNode> parseExpression(String expression) {
 565             if (StringUtils.isEmpty(expression)) {
 566                 return new ArrayList<ExpressionNode>();
 567             }
 568
 569             List<ExpressionNode> listOperator = new ArrayList<ExpressionNode>(10);
 570             Stack<ExpressionNode> stackOperator = new Stack<ExpressionNode>();
 571
 572             ExpressionParser expParser = new ExpressionParser(expression);
 573             ExpressionNode beforeExpNode = null; // 前一个节点
 574             ExpressionNode unitaryNode = null; // 一元操作符
 575             ExpressionNode expNode;
 576             // 是否需要操作数
 577             boolean requireOperand = false;
 578
 579             while ((expNode = expParser.readNode()) != null) {
 580                 if ((expNode.getType() == ExpressionNodeType.Numeric)
 581                         || (expNode.getType() == ExpressionNodeType.String)
 582                         || (expNode.getType() == ExpressionNodeType.Date)) {
 583                     // 操作数, 直接加入后缀表达式中
 584                     if (unitaryNode != null) {
 585                         // 设置一元操作符节点
 586                         expNode.setUnitaryNode(unitaryNode);
 587                         unitaryNode = null;
 588                     }
 589
 590                     listOperator.add(expNode);
 591                     requireOperand = false;
 592                     continue;
 593                 } else if (expNode.getType() == ExpressionNodeType.LParentheses) {
 594                     // 左括号, 直接加入操作符栈
 595                     stackOperator.push(expNode);
 596                     continue;
 597                 } else if (expNode.getType() == ExpressionNodeType.RParentheses) {
 598                     // 右括号则在操作符栈中反向搜索,直到遇到匹配的左括号为止,将中间的操作符依次加到后缀表达式中。
 599                     ExpressionNode lpNode = null;
 600                     while (stackOperator.size() > 0) {
 601                         lpNode = stackOperator.pop();
 602                         if (lpNode.getType() == ExpressionNodeType.LParentheses)
 603                             break;
 604                         listOperator.add(lpNode);
 605                     }
 606                     if (lpNode == null || lpNode.getType() != ExpressionNodeType.LParentheses) {
 607                         throw new ExpressionException(String.format("在表达式\"%s\"中没有与在位置(%s)上\")\"匹配的\"(%s)\"字符!",expParser.getExpression(), expParser.getPosition()));
 608                     }
 609                 } else {
 610                     if (stackOperator.size() == 0) {
 611                         // 第一个节点则判断此节点是否是一元操作符"+,-,!,("中的一个,否则其它都非法
 612                         if (listOperator.size() == 0 && !(expNode.getType() == ExpressionNodeType.LParentheses
 613                                 || expNode.getType() == ExpressionNodeType.Not)) {
 614                             // 后缀表达式没有任何数据则判断是否是一元操作数
 615                             if (ExpressionNode.IsUnitaryNode(expNode.getType())) {
 616                                 unitaryNode = expNode;
 617                             } else {
 618                                 // 丢失操作数
 619                                 throw new ExpressionException(String.format("表达式\"%s\"在位置(%s)上缺少操作数!",
 620                                         expParser.getExpression(), expParser.getPosition()));
 621                             }
 622                         } else {
 623                             // 直接压入操作符栈
 624                             stackOperator.push(expNode);
 625                         }
 626                         requireOperand = true; // 下一个节点需要操作数
 627                         continue;
 628                     } else {
 629                         if (requireOperand) {
 630                             // 如果需要操作数则判断当前的是否是"+","-"号(一元操作符),如果是则继续
 631                             if (ExpressionNode.IsUnitaryNode(expNode.getType()) && unitaryNode == null) {
 632                                 unitaryNode = expNode;
 633                             } else {
 634                                 // 丢失操作数
 635                                 throw new ExpressionException(String.format("表达式\"%s\"在位置({1})上缺少操作数!",
 636                                         expParser.getExpression(), expParser.getPosition()));
 637                             }
 638                         } else {
 639                             // 对前面的所有操作符进行优先级比较
 640                             do {
 641                                 // 取得上一次的操作符
 642                                 beforeExpNode = stackOperator.peek();
 643
 644                                 // 如果前一个操作符优先级较高,则将前一个操作符加入后缀表达式中
 645                                 if (beforeExpNode.getType() != ExpressionNodeType.LParentheses
 646                                         && (beforeExpNode.getPri() - expNode.getPri()) >= 0) {
 647                                     listOperator.add(stackOperator.pop());
 648                                 } else {
 649                                     break;
 650                                 }
 651
 652                             } while (stackOperator.size() > 0);
 653
 654                             // 将操作符压入操作符栈
 655                             stackOperator.push(expNode);
 656                             requireOperand = true;
 657                         }
 658                     }
 659                 }
 660             }
 661
 662             if (requireOperand) {
 663                 // 丢失操作数
 664                 throw new ExpressionException(
 665                         String.format("表达式\"%s\"在位置({1})上缺少操作数!", expParser.getExpression(), expParser.getPosition()));
 666             }
 667             // 清空堆栈
 668             while (stackOperator.size() > 0) {
 669                 // 取得操作符
 670                 beforeExpNode = stackOperator.pop();
 671                 if (beforeExpNode.getType() == ExpressionNodeType.LParentheses) {
 672                     throw new ExpressionException(String.format("表达式\"%s\"中括号不匹配,丢失右括号!", expParser.getExpression(),
 673                             expParser.getPosition()));
 674                 }
 675                 listOperator.add(beforeExpNode);
 676             }
 677
 678             return listOperator;
 679         }
 680
 681         /**
 682          * 对逆波兰表达式进行计算
 683          *
 684          * @param nodes
 685          * @return
 686          */
 687         @SuppressWarnings({ "rawtypes", "unchecked", "incomplete-switch" })
 688         private static  Object CalcExpression(List<ExpressionNode> nodes) {
 689             if (nodes == null || nodes.size() == 0)
 690                 return null;
 691
 692             if (nodes.size() > 1) {
 693                 int index = 0;
 694                 // 储存数据
 695                 ArrayList values = new ArrayList();
 696                 while (index < nodes.size()) {
 697                     ExpressionNode node = nodes.get(index);
 698
 699                     switch (node.getType()) {
 700                     // 如果是数字,则将值存入 values 中
 701                     case Numeric:
 702                     case String:
 703                     case Date:
 704                         values.add(node.getNumeric());
 705                         index++;
 706                         break;
 707                     default:
 708                         // 二元表达式,需要二个参数, 如果是Not的话,则只要一个参数
 709                         int paramCount = 2;
 710                         if (node.getType() == ExpressionNodeType.Not)
 711                             paramCount = 1;
 712                         // 计算操作数的值
 713                         if (values.size() < paramCount) {
 714                             throw new ExpressionException("缺少操作数");
 715                         }
 716                         // 传入参数
 717                         Object[] data = new Object[paramCount];
 718                         for (int i = 0; i < paramCount; i++) {
 719                             data[i] = values.get(index - paramCount + i);
 720                         }
 721                         // 将计算结果再存入当前节点
 722                         node.setNumeric(calculate(node.getType(), data));
 723                         node.setType(ExpressionNodeType.Numeric);
 724                         // 将操作数节点删除
 725                         for (int i = 0; i < paramCount; i++) {
 726                             nodes.remove(index - i - 1);
 727                             values.remove(index - i - 1);
 728                         }
 729                         index -= paramCount;
 730                         break;
 731                     }
 732
 733                 }
 734             }
 735
 736             if (nodes.size() != 1) {
 737                 throw new ExpressionException("缺少操作符或操作数");
 738             }
 739             switch (nodes.get(0).getType()) {
 740             case Numeric:
 741                 return nodes.get(0).getNumeric();
 742
 743             case String:
 744             case Date:
 745                 return nodes.get(0).getNumeric().toString().replace("\"", "");
 746             }
 747             throw new ExpressionException("缺少操作数");
 748         }
 749
 750         /**
 751          * 计算节点的值
 752          *
 753          * @param nodeType
 754          *            节点的类型
 755          * @param data
 756          *            要计算的值,有可能是两位或一位数
 757          * @return
 758          */
 759         @SuppressWarnings("incomplete-switch")
 760         private static  Object calculate(ExpressionNodeType nodeType, Object[] data) {
 761             double d1, d2;
 762             boolean b1, b2;
 763             Date time1, time2;
 764             Object obj1 = data[0];
 765             Object obj2 = data[1];
 766             String str1 = obj1.toString();
 767             String str2 = obj2.toString();
 768
 769             boolean dateflag = ExpressionNode.isDatetime(str1) || ExpressionNode.isDatetime(str2);
 770             boolean strflag = str1.contains("\"") || str2.contains("\"");
 771             str1 = str1.replace("\"", "");
 772             str2 = str2.replace("\"", "");
 773
 774             switch (nodeType) {
 775             case Plus:
 776                 if (!strflag) {
 777                     d1 = ConvertToDecimal(obj1);
 778                     d2 = ConvertToDecimal(obj2);
 779                     return (d1 + d2);
 780                 }
 781                 return new StringBuffer(str1 + str2).toString();
 782             case Subtract:
 783                 d1 = ConvertToDecimal(obj1);
 784                 d2 = ConvertToDecimal(obj2);
 785                 return d1 - d2;
 786             case MultiPly:
 787                 d1 = ConvertToDecimal(obj1);
 788                 d2 = ConvertToDecimal(obj2);
 789                 return d1 * d2;
 790             case Divide:
 791                 d1 = ConvertToDecimal(obj1);
 792                 d2 = ConvertToDecimal(obj2);
 793                 if (d2 == 0)
 794                     throw new RuntimeException();
 795                 return d1 / d2;
 796             case Power:
 797                 d1 = ConvertToDecimal(obj1);
 798                 d2 = ConvertToDecimal(obj2);
 799                 return Math.pow((double) d1, (double) d2);
 800             case Mod:
 801                 d1 = ConvertToDecimal(obj1);
 802                 d2 = ConvertToDecimal(obj2);
 803                 if (d2 == 0)
 804                     throw new RuntimeException();
 805                 return d1 % d2;
 806             case BitwiseAnd:
 807                 d1 = ConvertToDecimal(obj1);
 808                 d2 = ConvertToDecimal(obj2);
 809                 return (int) d1 & (int) d2;
 810             case BitwiseOr:
 811                 d1 = ConvertToDecimal(obj1);
 812                 d2 = ConvertToDecimal(obj2);
 813                 return (int) d1 | (int) d2;
 814             case And:
 815                 b1 = ConvertToBool(obj1);
 816                 b2 = ConvertToBool(obj2);
 817                 return b1 && b2;
 818             case Or:
 819                 b1 = ConvertToBool(obj1);
 820                 b2 = ConvertToBool(obj2);
 821                 return b1 || b2;
 822             case Not:
 823                 b1 = ConvertToBool(obj1);
 824                 return !b1;
 825             case Equal:
 826                 if (!dateflag) {
 827                     if (strflag) {
 828                         return str1.equals(str2);
 829                     }
 830                     d1 = ConvertToDecimal(obj1);
 831                     d2 = ConvertToDecimal(obj2);
 832                     return (d1 == d2);
 833                 }
 834                 time1 = DateUtils.parseDate(str1);
 835                 time2 = DateUtils.parseDate(str2);
 836
 837                 return (time1.getTime() == time2.getTime());
 838             case Unequal:
 839                 if (!dateflag) {
 840                     if (strflag) {
 841                         return (!str1.equals(str2));
 842                     }
 843                     d1 = ConvertToDecimal(obj1);
 844                     d2 = ConvertToDecimal(obj2);
 845                     return (d1 != d2);
 846                 }
 847                 time1 = DateUtils.parseDate(str1);
 848                 time2 = DateUtils.parseDate(str2);
 849
 850                 return (time1.getTime() != time2.getTime());
 851             case GT:
 852
 853                 if (!dateflag) {
 854                     d1 = ConvertToDecimal(obj1);
 855                     d2 = ConvertToDecimal(obj2);
 856                     return (d1 > d2);
 857                 }
 858                 time1 = DateUtils.parseDate(str1);
 859                 time2 = DateUtils.parseDate(str2);
 860                 return (time1.getTime() > time2.getTime());
 861
 862             case LT:
 863
 864                 if (!dateflag) {
 865                     d1 = ConvertToDecimal(obj1);
 866                     d2 = ConvertToDecimal(obj2);
 867                     return (d1 < d2);
 868                 }
 869                 time1 = DateUtils.parseDate(str1);
 870                 time2 = DateUtils.parseDate(str2);
 871                 return (time1.getTime() < time2.getTime());
 872
 873             case GTOrEqual:
 874
 875                 if (!dateflag) {
 876                     d1 = ConvertToDecimal(obj1);
 877                     d2 = ConvertToDecimal(obj2);
 878                     return (d1 >= d2);
 879                 }
 880                 time1 = DateUtils.parseDate(str1);
 881                 time2 = DateUtils.parseDate(str2);
 882                 return (time1.getTime() >= time2.getTime());
 883
 884             case LTOrEqual:
 885                 if (!dateflag) {
 886                     d1 = ConvertToDecimal(obj1);
 887                     d2 = ConvertToDecimal(obj2);
 888                     return (d1 <= d2);
 889                 }
 890                 time1 = DateUtils.parseDate(str1);
 891                 time2 = DateUtils.parseDate(str2);
 892                 return (time1.getTime() <= time2.getTime());
 893             case LShift:
 894                 d1 = ConvertToDecimal(obj1);
 895                 d2 = ConvertToDecimal(obj2);
 896                 return (long) d1 << (int) d2;
 897
 898             case RShift:
 899                 d1 = ConvertToDecimal(obj1);
 900                 d2 = ConvertToDecimal(obj2);
 901                 return (long) d1 >> (int) d2;
 902             case Like:
 903                 if (!strflag) {
 904                     return false;
 905                 }
 906                 return str1.contains(str2);
 907             case NotLike:
 908                 if (!strflag) {
 909                     return false;
 910                 }
 911                 return !str1.contains(str2);
 912             case StartWith:
 913                 if (!strflag) {
 914                     return false;
 915                 }
 916                 return str1.startsWith(str2);
 917             case EndWith:
 918                 if (!strflag) {
 919                     return false;
 920                 }
 921                 return str1.endsWith(str2);
 922             }
 923
 924             return 0;
 925         }
 926
 927         /**
 928          * 某个值转换为bool值
 929          *
 930          * @param value
 931          * @return
 932          */
 933         private static  Boolean ConvertToBool(Object value) {
 934             if (value instanceof Boolean) {
 935                 return (Boolean) value;
 936             } else {
 937                 return value != null;
 938             }
 939         }
 940
 941         /**
 942          * 将某个值转换为decimal值
 943          *
 944          * @param value
 945          * @return
 946          */
 947         private static  Double ConvertToDecimal(Object value) {
 948             if (value instanceof Boolean) {
 949                 return ((Boolean) value ? 1d : 0d);
 950             } else {
 951                 return Double.parseDouble(value.toString());
 952             }
 953         }
 954
 955         /**
 956          *
 957          * @param expression
 958          *            要计算的表达式,如"1+2+3+4"
 959          * @return 返回计算结果,如果带有逻辑运算符则返回true/false,否则返回数值
 960          */
 961         public Object eval(String expression) {
 962             return CalcExpression(parseExpression(expression));
 963         }
 964
 965         public  Object evalThreeOperand(String expression) {
 966             int index = expression.indexOf("?");
 967             if (index > -1) {
 968                 String str = expression.substring(0, index);
 969                 String str2 = expression.substring(index + 1);
 970                 index = str2.indexOf(":");
 971
 972                 if (Boolean.parseBoolean((CalcExpression(parseExpression(str))).toString())) {
 973                     return eval(str2.substring(0, index));
 974                 }
 975                 return eval(str2.substring(index + 1));
 976             }
 977             return CalcExpression(parseExpression(expression));
 978         }
 979
 980     }
 981
 982 //    /**
 983 //     * 测试
 984 //     *
 985 //     * @方法名:main
 986 //     * @参数 @param args
 987 //     * @返回类型 void
 988 //     */
 989 //    public static void main(String[] args) {
 990 //        String s1 = "1+2+3+4";
 991 //        System.out.println(ExpressionEvaluator.eval(s1));
 992 //
 993 //        String s2 = "(20 - 6) < 3";
 994 //        System.out.println(ExpressionEvaluator.eval(s2));
 995 //
 996 //        String s3 = "(3 + 1) == 4 && 5 > (2 + 3)";
 997 //        System.out.println(ExpressionEvaluator.eval(s3));
 998 //
 999 //        String s4 = "\"hello\" == \"hello\" && 3 != 4";
1000 //        System.out.println(ExpressionEvaluator.eval(s4));
1001 //
1002 //        String s5 = "\"helloworld\" @ \"hello\" &&  \"helloworld\" !@ \"word\" ";
1003 //        System.out.println(ExpressionEvaluator.eval(s5));
1004 //
1005 //    }
1006
1007 }

转载于:https://www.cnblogs.com/tangzeqi/p/8046732.html

Java 表达式解析(非原创)相关推荐

  1. Java表达式解析器

    1.阿里巴巴QLExpress https://github.com/alibaba/QLExpress/blob/master/README.md 由阿里的电商业务规则.表达式(布尔组合).特殊数学 ...

  2. 【Java工具类】学会MVEL2.0,表达式解析再不怕

    文章目录 常见的表达式引擎 一.什么是MVEL? 二.快速入门 三.语法 1.基本语法 1.1 简单属性表达式 1.2 布尔表达式 1.3 复合语句表达式 1.4 返回值 2. 操作符 2.1 一元操 ...

  3. java jexl 工具类_jexl表达式解析、计算工具类.md

    jexl表达式解析.计算工具类.md 根据表达式可以动态反向解析出变量:适合动态表达式,参数未知场景 如 (A0.2+B0.8)/C 解析出 A\B\C,把ABC参数值代入计算 初始化引擎 priva ...

  4. Java调优遇到的姿势【非原创】

    Java调优 本文简单说一说JVM应如何调优.引用[廖雪峰 / 编程 / 2020/3/12 12:39 ] Java语言本身的成功,除了天时地利人和,JVM功不可没. 毫不夸张地说,JVM是现代软件 ...

  5. Java解析MDB(上)-纯JDBC解析非空间数据

    MDB格式数据可以用来存储空间信息,也可以用来存储非空间信息.如果用来存储非空间数据的话,跟普通的excel表格及关系型数据库是一样的.您可以使用微软的access数据库直接打开,也可以使用arcgi ...

  6. java 自定义表达式_Java中使用Groovy实现自定义表达式解析

    Groovy作为一种JVM-Based语言,目前普及程度正在提高.本文演示一下在Java类中,通过继承GDK的groovy.lang.Script类如何支持自定义表达式解析功能. 输入: 表示一行数据 ...

  7. JAVA关系表达式解析微引擎

    为什么80%的码农都做不了架构师?>>>    背景介绍: 为什么需要这个表达式解析微引擎? 首先这个引擎是产生于调用链路跟踪系统,我们知道在调用跟踪系统里经常会根据关键字搜索日志但 ...

  8. Java基础学习之数据结构:利用栈和队列完成表达式解析

    在阅读本篇文章之前,相信大家对栈和队列的概念已经有了基本的认识.何为栈?栈就是一种"先进后出"存储数据的结构,即最先进栈的数据,最后出栈: 通常,栈的开口端被称为栈顶:相应地,封口 ...

  9. css总结-笔记--部分非原创--属于资源整合

    文章目录 一.css基础教程 1.选择器等级 1.1层叠次序 1.2css三大特性 层叠性原则 继承性 优先级 2.基础语法 2.1声明 2.2值的写法和单位 2.2.1颜色的几种写法(用红色举例) ...

最新文章

  1. jquery 取消 radio checked 属性,重新选中的问题解决
  2. 深度丨有生之年,人工智能会给世界带来什么变化?
  3. Spring系列之AOP分析之为目标类挑选合适的Advisor(五)
  4. Python 应用领域
  5. 命名空间不能直接包含字段或方法之类的成员是什么意思_Python 学习笔记之类与实例...
  6. php parse url ctf,【SSRF】如何绕过filter_var(), preg_match() 和 parse_url()
  7. 小汤学编程之JAVA基础day08——面向对象(三):抽象类与接口
  8. spring controller 增加header字段forward_Spring 注解编程之模式注解
  9. 一道组合数学题-马拦过河卒,很精彩
  10. 使用zTree和json构建简单树节点
  11. centos6.5 yum安装php5.5,mysql5.5.46 ,aphche 2.2.15
  12. php怎么文字加粗体代码,html字体加粗用css设置文字粗体样式
  13. 识别到硬盘 计算机不显示盘符,Win10系统下移动硬盘可以识别但是不显示盘符的解决方法...
  14. html 播放amr ios,关于iOS设备以amr格式播放音频文件
  15. 路由器外接硬盘做nas可行吗?
  16. 广义相对论-学习记录7-第三章-张量分析与黎曼几何4
  17. 关于选项卡的切换——JS实现
  18. 苹果手机python3ide闪退_【报Bug】IOS 12.3 app在非特定页面频发闪退
  19. 升级Windows11遇到VirtualBox兼容性问题(附解决办法)
  20. [沟通能力] 述职,你搞定了吗?

热门文章

  1. github怎么切换到gitee_Github 如何和 Gitee 进行同步?
  2. 2021年黑龙江高考成绩查询,黑龙江省招生考试信息港:2021年黑龙江高考成绩查询入口、查分系统...
  3. MYSQL5.6创建表报错 [ERR] 1273 - Unknown collation: ‘utf8mb4_0900_ai_ci‘
  4. textarea 内容前端展示换行php处理
  5. 极速安装JumpServer - 官方文档版
  6. 第8周课堂测试3(课上未完成)
  7. Java基础(二):基本数据类型和变量类型
  8. 支付宝WAP支付接口开发
  9. PHP 服务器变量 $_SERVER(转)
  10. 关于web.xml中不能识别taglib的问题