Java 表达式解析(非原创)
因项目需要,在网上找来一套表达式解析方法,由于原来的方法太过于零散,不利于移植,现在整理在同一文件内;
文件中包含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 }