之前简单的介绍了这个基于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方法会将两个值进行各种运算操作,也是在这个方法中,我们填写扩展的一些方法。

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

基于Java的简易表达式解析工具(二)的更多相关文章

  1. 基于Java的简易表达式解析工具(一)

    最近需要用到相关表达式解析的工具,然后去网上搜索,找到了一个用C#写的表达式解析工具,仔细看了功能后发现,这正是我需要的,如果我能将它改造成基于Java语言的方式,岂不是更好吗,所以花了一段时间,把网 ...

  2. java后台常用json解析工具问题小结

    若排版紊乱可查看我的个人博客原文地址 java后台常用json解析工具问题小结 这里不细究造成这些问题的底层原因,只是单纯的描述我碰到的问题及对应的解决方法 jackson将java对象转json字符 ...

  3. java微信开发API解析(二)-获取消息和回复消息

    java微信开发API解析(二)-获取消息和回复消息 说明 * 本演示样例依据微信开发文档:http://mp.weixin.qq.com/wiki/home/index.html最新版(4/3/20 ...

  4. Java高级面试题解析(二):百度Java面试题前200页(精选)

    基本概念 操作系统中 heap 和 stack 的区别 heap是堆,stack是栈,是两种不同的数据结构.堆是队列优先,先进先出:栈是先进后出. 在java多线程中,每个线程都有自己的栈:不同的线程 ...

  5. 你必须掌握的Java基础:JSON解析工具-json-lib

    一.简介  json-lib是一个Java类库,提供将Java对象,包括beans,maps,collections,java arrays和xml等转换成JSON,或者反向转换的功能. 二.准备 在 ...

  6. Java数据结构与算法解析(十二)——散列表

    散列表概述 散列表就是一种以 键-值(key-indexed) 存储数据的结构,我们只要输入待查找的值即key,即可查找到其对应的值. 散列表的思路很简单,如果所有的键都是整数,那么就可以使用一个简单 ...

  7. JSON语言规范与Java中两种解析工具基本使用

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6652250.html  一:JSON语言规范 一言以蔽之:“一个 :一个键值对,一个{}一个对象,一个[]一个 ...

  8. 基于Java的四大开源测试工具

    摘要:成功的应用程序离不开测试人员和QA团队反复地测试,应用程序在进行最后的部署之前,需要通过测试来确保它的负载管理能力以及在特殊情况下的工作条件和工作加载情况. %R[)vA t]N0 测试是应用程 ...

  9. java基础篇---XML解析(二)

    XML解析之最流行的方式:DOM4J dom4j是使用java语言编写的,用于读,写,操作XML的一套组件 dom4j是一个开源的java组件,可从http://sourceforge.net/pro ...

随机推荐

  1. 集合(四)HashMap

    之前的List,讲了ArrayList.LinkedList,最后讲到了CopyOnWriteArrayList,就前两者而言,反映的是两种思想: (1)ArrayList以数组形式实现,顺序插入.查 ...

  2. Delphi XE6 Android拨号函数

    http://blog.sina.com.cn/s/blog_44fa172f0101rpex.html Delphi XE6 Android拨号函数 (2014-05-07 17:48:51) 转载 ...

  3. Android-ByteUtil工具类

    Byte处理转换相关的工具类: public class ByteUtil { private ByteUtil(){} /** * 把byte[] 转成 Stirng * @param bytes ...

  4. Global.asax和HttpModule的执行顺序

    Application_Start-->用户自定义的HttpModule-->Application_BeginRequest   (注册->调用) 看到Init方法(在用户自定义的 ...

  5. 使用ABP框架踩过的坑系列4

    数据库连接和事务管理,是数据库应用中的最重要概念之一.做过的人,都会头疼:何时Open一个连接?何时Start一个事务?何时Dispose这个连接?... ABP框架试图用一个叫做UnitOfWork ...

  6. electron-vue 开发环境搭建(Windows环境)

    1.安装 Node.js,一切都基于这个.安装完成后,终端输入 node -v 验证. 2.建立自己的项目目录,然后进入目录. 安装 vue-cli ,终端输入 npm install -g vue- ...

  7. C#操作Xml树的扩展类

    本文提供一个操作Xml树的扩展类,与将xml字符串直接映射成实体对象的使用方法,供大家参考,学习. 下面附上源码 using System; using System.Collections.Gene ...

  8. Greedy- 621. Task Scheduler

    Given a char array representing tasks CPU need to do. It contains capital letters A to Z where diffe ...

  9. Access 2010 应用基础 单元三:SQL查询

    导语:Access查询中拉差距的部分 简单查询 [是基于单个表的查询] 无条件从数据表中选择部分字段 Select 字段列表 from 数据表 无条件从数据表中选择全部字段 Select 字段列表 f ...

  10. 频繁项集挖掘之apriori和fp-growth

    Apriori和fp-growth是频繁项集(frequent itemset mining)挖掘中的两个经典算法,虽然都是十几年前的,但是理解这两个算法对数据挖掘和学习算法都有很大好处.在理解这两个 ...