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

时间:2021-08-31 13:12:52

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

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

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

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

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

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

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

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

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

  1. public class ExpressionException extends RuntimeException{
  2. private static final long serialVersionUID = 1L;
  3. public ExpressionException() {
  4. super();
  5. }
  6. public ExpressionException(String msg) {
  7. super(msg);
  8. }
  9. public ExpressionException(String msg, Throwable cause) {
  10. super(msg,cause);
  11. }
  12. public ExpressionException(Throwable cause) {
  13. super(cause);
  14. }
  15. }

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

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

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

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

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

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

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