我正在寻找一种相对简单的方法(与编写解析器相比)来在Java中评估布尔表达式,并且我不想使用JEP库。
我有一个字符串表达式,例如:(x > 4 || x < 8 && p > 6)
,我的目标是用实际值替换变量。
是否有一种方法可以评估这个表达式?需要注意的是,这可以是任意深度嵌套的表达式,因此编写解析器会非常复杂。
我正在寻找一种相对简单的方法(与编写解析器相比)来在Java中评估布尔表达式,并且我不想使用JEP库。
我有一个字符串表达式,例如:(x > 4 || x < 8 && p > 6)
,我的目标是用实际值替换变量。
是否有一种方法可以评估这个表达式?需要注意的是,这可以是任意深度嵌套的表达式,因此编写解析器会非常复杂。
使用Apache Commons Jexl,它专门为这种需求而设计。
使用jexl(http://commons.apache.org/jexl/),您可以像这样完成此操作
JexlEngine jexl = new JexlEngine();
jexl.setSilent(true);
jexl.setLenient(true);
Expression expression = jexl.createExpression("(a || b && (c && d))");
JexlContext jexlContext = new MapContext();
//b and c and d should pass
jexlContext.set("b",true);
jexlContext.set("c",true);
jexlContext.set("d",true);
assertTrue((Boolean)expression.evaluate(jexlContext));
jexlContext = new MapContext();
//b and c and NOT d should be false
jexlContext.set("b",true);
jexlContext.set("c",true);
//note this works without setting d to false on the context
//because null evaluates to false
assertFalse((Boolean)expression.evaluate(jexlContext));
(a||b)&&(c&&d)
的示例,看起来已经修复了。只有'a'的值为'false',这是正确的。 - membersound ExpressionsEvaluator evalExpr = ExpressionsFactory.create("(x > 4 || x < 8 && p > 6)");
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("x", 100);
variables.put("p", 10);
evalExpr.eval();
有一个API可用,位于http://lts.online.fr/dev/java/math.evaluator/
示例:
MathEvaluator m = new MathEvaluator("-5-6/(-2) + sqr(15+x)");
m.addVariable("x", 15.1d);
System.out.println( m.getValue() );
// Compile the expression once; relatively slow.
ExpressionEvaluator ee = new ExpressionEvaluator(
"c > d ? c : d", // expression
int.class, // expressionType
new String[] { "c", "d" }, // parameterNames
new Class[] { int.class, int.class } // parameterTypes
);
// Evaluate it with varying parameter values; very fast.
Integer res = (Integer) ee.evaluate(
new Object[] { // parameterValues
new Integer(10),
new Integer(11),
}
);
System.out.println("res = " + res);
JUEL 提供了 Java 统一表达式语言的实现,而不需要显式地绑定到 JSP。这里是它的快速入门指南,其中表达式求值(该页面上的#3)是您感兴趣的部分。
另外,Spring 3.0 提供了自己的(虽然有些相似)表达式语言。不过,只有在您已经使用 Spring 的情况下才有意义选择此选项 - 我不会仅为 EL 引入它。