JAVA - 表达式解析和评估库

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11947553/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 07:02:53  来源:igfitidea点击:

JAVA - Expression parsing & evaluating library

javaexpression

提问by duduamar

I'm looking for a JAVA library to parse & evaluate expression. I searched and tried some libraries like Apache's JEXL and Jeval, but they are not exactly what I need.

我正在寻找一个 JAVA 库来解析和评估表达式。我搜索并尝试了一些库,如 Apache 的 JEXL 和 Jeval,但它们并不是我所需要的。

My requirements:

我的要求:

  1. Support all value types (i.e. int,double,boolean,String, etc.)
  2. Support all known mathematical & logical operators (+,-,*,<,<=,etc.)
  3. Support variables (without any special notation - for example in Jeval variable a should be written like #{a} - not good enough for me)
  4. Support custom functions - with type enforcement and validation
  1. 支持所有值类型(即int、double、boolean、String等)
  2. 支持所有已知的数学和逻辑运算符(+、-、*、<、<= 等)
  3. 支持变量(没有任何特殊符号 - 例如在 Jeval 变量 a 应该写成 #{a} - 对我来说不够好)
  4. 支持自定义函数 - 具有类型强制和验证

Any recommendations?

有什么建议吗?

回答by lost

Try Janino. It's a runtime in-memory compiler that can be used as an expression evaluator. Maybe it is the right thing for you.

试试贾尼诺。它是一个运行时内存编译器,可用作表达式评估器。也许这对你来说是正确的。

回答by Hiery Nomus

Like suggested, you can use JavaScript. But also you could take a look at Spring ELwhich has support for your requirements.

就像建议的那样,您可以使用 JavaScript。但您也可以查看Spring EL,它支持您的要求。

回答by Leroy Kegan

You can try mXparser- it supports significant part of your requirements:

您可以尝试mXparser- 它支持您的大部分需求:

  1. It is based on double, so int is supported, additionally boolean is supportedas true = 1 and false = 0. Unfortunately strings are not supported.
  1. 它基于双精度型,因此支持 int,此外还支持布尔值,如 true = 1 和 false = 0。不幸的是,不支持字符串。

Boolean example:

布尔示例:

import org.mariuszgromada.math.mxparser.*;
...
...
Constant T = new Constant("T = 1");
Constant F = new Constant("F = 0");
Expression e = new Expression("T && (F || (F && T))", T, F);
System.out.println(e.getExpressionString() + " = " + e.calculate());

Result:

结果:

T && (F || (F && T)) = 0.0
  1. mXparser has broad support for operators, functions, etc.. Check mXparser math collection. What is nice you can use help functionality inside the library.
  1. mXparser对运算符、函数等有广泛的支持。检查mXparser 数学集合。您可以使用库中的帮助功能有什么好处。

Example:

例子:

import org.mariuszgromada.math.mxparser.*;
...
...
mXparser.consolePrintHelp("operator");

Result:

结果:

Help content: 

    2. +                   <Operator>              addition
    3. -                   <Operator>              subtraction
    4. *                   <Operator>              multiplication
    5. /                   <Operator>              division
    6. ^                   <Operator>              exponentiation
    7. !                   <Operator>              factorial
    8. #                   <Operator>              modulo function
    9. &                   <Boolean Operator>      logical conjunction (AND)
   10. &&                  <Boolean Operator>      logical conjunction (AND)
   11. /\                  <Boolean Operator>      logical conjunction (AND)
   12. ~&                  <Boolean Operator>      NAND - Sheffer stroke
   13. ~&&                 <Boolean Operator>      NAND - Sheffer stroke
   14. ~/\                 <Boolean Operator>      NAND - Sheffer stroke
   15. |                   <Boolean Operator>      logical disjunction (OR)
   16. ||                  <Boolean Operator>      logical disjunction (OR)
   17. \/                  <Boolean Operator>      logical disjunction (OR)
   18. ~|                  <Boolean Operator>      logical NOR
   19. ~||                 <Boolean Operator>      logical NOR
   20. ~\/                 <Boolean Operator>      logical NOR
   21. (+)                 <Boolean Operator>      exclusive or (XOR)
   22. -->                 <Boolean Operator>      implication (IMP)
   23. <--                 <Boolean Operator>      converse implication (CIMP)
   24. -/>                 <Boolean Operator>      material nonimplication (NIMP)
   25. </-                 <Boolean Operator>      converse nonimplication (CNIMP)
   26. <->                 <Boolean Operator>      logical biconditional (EQV)
   27. ~                   <Boolean Operator>      negation
   28. ?                   <Boolean Operator>      negation
  162. add                 <Variadic Function>     (2.4) Summation operator add(a1,a2,a3,...,an)
  168. sum                 <Calculus Operator>     summation operator (SIGMA) sum(i, from, to, f(i,...))
  169. prod                <Calculus Operator>     product operator (PI) prod(i, from, to, f(i,...))
  170. int                 <Calculus Operator>     definite integral operator ( int(f(x,...), x, a, b) )
  171. der                 <Calculus Operator>     derivative operator ( der(f(x,...), x) ) 
  172. der-                <Calculus Operator>     left derivative operator ( der-(f(x,...), x) ) 
  173. der+                <Calculus Operator>     right derivative operator ( der+(f(x,...), x) ) 
  174. dern                <Calculus Operator>     n-th derivative operator ( dern(f(x,...), x) ) 
  175. diff                <Calculus Operator>     forward difference operator
  176. difb                <Calculus Operator>     backward difference operator
  177. avg                 <Calculus Operator>     (2.4) Average operator avg(i, from, to, f(i,...))
  178. vari                <Calculus Operator>     (2.4) Bias-corrected sample variance operator vari(i, from, to, f(i,...))
  179. stdi                <Calculus Operator>     (2.4) Bias-corrected sample standard deviation operator stdi(i, from, to, f(i,...))
  180. mini                <Calculus Operator>     (2.4) Minimum value mini(i, from, to, f(i,...))
  181. maxi                <Calculus Operator>     (2.4) Maximum value maxi(i, from, to, f(i,...))
  182. solve               <Calculus Operator>     (4.0) f(x) = 0 equation solving, function root finding: solve( f(x,...), x, a, b )
  301. @~                  <Bitwise Operator>      (4.0) Bitwise unary complement
  302. @&                  <Bitwise Operator>      (4.0) Bitwise AND
  303. @^                  <Bitwise Operator>      (4.0) Bitwise exclusive OR
  304. @|                  <Bitwise Operator>      (4.0) Bitwise inclusive OR
  305. @<<                 <Bitwise Operator>      (4.0) Signed left shift
  306. @>>                 <Bitwise Operator>      (4.0) Signed right shift
  1. User defined variablesand user defined constantsare created without any special form.
  1. 用户定义变量用户定义常量的创建没有任何特殊形式。

Example:

例子:

import org.mariuszgromada.math.mxparser.*;
...
...
Argument x = new Argument("x = 10");
Constant y = new Constant("y = 2");
Expression e = new Expression("x/y", x, y);
System.out.println(e.getExpressionString() + " = " + e.calculate());

Result:

结果:

x/y = 5.0

Additionally please check: a) Tutorial - User defined arguments, b) Tutorial - User defined constants.

另外请检查:a)教程 - 用户定义的参数,b)教程 - 用户定义的常量

  1. User defined functionsare fully supported.
  1. 完全支持用户定义的函数

Example 1 - body defined in run-time:

示例 1 - 在运行时定义的主体:

import org.mariuszgromada.math.mxparser.*;
...
...
Function f = new Function("f(x,y) = x*y");
Expression e = new Expression("20-f(2,5)",f);
System.out.println(e.getExpressionString() + " = " + e.calculate());

Result 1

结果 1

20-f(2,5) = 10.0

Example 2 - body extended via your own implementation:

示例 2 - 通过您自己的实现扩展的主体:

import org.mariuszgromada.math.mxparser.*;
...
...
/*
 * Implementing FunctionExtension interface
 */
public class Addition implements FunctionExtension {
   double x;
   double y;
   public Addition() {
      x = Double.NaN;
      y = Double.NaN;
   }
   public Addition(double x, double y) {
      this.x = x;
      this.y = y;
   }
   public int getParametersNumber() {
      return 2;
   }
   public void setParameterValue(int argumentIndex, double argumentValue) {
      if (argumentIndex == 0) x = argumentValue;
      if (argumentIndex == 1) y = argumentValue;
   }
   public double calculate(double... params) {
      return x+y;
   }
   public FunctionExtension clone() {
      return new Addition(x, y);
   }   
}

/*
* Creating extended function
*/
Function f = new Function("f", new Addition());
mXparser.consolePrintln("f.calculate(1,2) = " + f.calculate(1,2) );
/*
* Using extended function in expression
*/
Expression e = new Expression("f(2,3)", f);
System.out.println(e.getExpressionString() + " = " + e.calculate() );

Result 2:

结果 2:

f.calculate(1,2) = 3.0
f(2,3) = 5.0

Additionally it is worth to follow the wholemXparser Tutorial.

此外,值得遵循整个mXparser 教程

Found recently - in case you would like to try the syntax (and see the advanced use case) you can download the ScalarCalculatorappthat is powered by mXparser.

最近发现 - 如果您想尝试语法(并查看高级用例),您可以下载由 mXparser 提供支持的标量计算器应用程序

Best regards

最好的祝福

回答by Lukas Eder

Here would be a couple of workaround solutions that you could choose from, if you don't find an actual Java expression evaluation library:

如果您没有找到实际的 Java 表达式评估库,那么您可以从以下几个变通解决方案中进行选择:

  • Evaluate your expressions using XPath.
    • Pros: XPath knows logical operators, and you can implement variables and custom functions using Xalan's extensions
    • Cons: XPath has fewer types than Java
  • Evaluate your expressions using JavaScript.
    • Pros: Javascript is very flexible and will still be suitable when your requirements tighten. You can implement variables and custom functions using Javascript as well
    • Cons: Javascript has fewer types than Java
  • Evaluate your expressions using JSP's expression language (e.g. with JUEL)
  • 使用 XPath 评估您的表达式。
    • 优点:XPath 知道逻辑运算符,您可以使用 Xalan 的扩展来实现变量和自定义函数
    • 缺点:XPath 的类型比 Java 少
  • 使用 JavaScript 评估您的表达式。
    • 优点:Javascript 非常灵活,当您的要求收紧时仍然适用。您也可以使用 Javascript 实现变量和自定义函数
    • 缺点:Javascript 的类型比 Java 少
  • 使用 JSP 的表达式语言(例如使用JUEL)评估您的表达式