我正在寻找一种相对简单(与编写解析器相比)的方式来评估Java中的布尔表达式,并且我不想使用JEP库。Java中的布尔表达式评估
我有一个字符串表达式,如:(x > 4 || x < 8 && p > 6)
,我的目标是用值替换变量。
有没有一种方法可以评估这个表达式?
请记住,这可以是任何深度级别,因此编写解析器将非常复杂。
我正在寻找一种相对简单(与编写解析器相比)的方式来评估Java中的布尔表达式,并且我不想使用JEP库。Java中的布尔表达式评估
我有一个字符串表达式,如:(x > 4 || x < 8 && p > 6)
,我的目标是用值替换变量。
有没有一种方法可以评估这个表达式?
请记住,这可以是任何深度级别,因此编写解析器将非常复杂。
JUEL提供了Java的统一表达式语言的实现,而不必明确地绑定到JSP。这是它的Quick Start guide,表达式评估(该页上的#3)是您感兴趣的部分。
或者,Spring 3.0提供了它自己的(尽管有点类似)表达式语言。这个选项只有在你已经使用Spring的时候才有意义 - 不过我不会为了EL而使用它。
使用Apache Commons Jexl;这正是为这样的要求而设计的。
有可用的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());
这个链接似乎没有工作,至少在撰写本文时。此外,这个库是否支持比较运算符和像OP那样的布尔值? – andr 2012-12-31 11:18:22
这里是表达评估框架
信息页面的最新资源在http://expressionoasis.vedantatree.com/
我发现这里列出的库太复杂了,无法满足我的需求。我结束了使用Fscript: http://fscript.sourceforge.net/
使用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));
我与jexl有一个问题是它的优先级。我有一个需要评估||的案例在评估&&之前。所以上面的表达式变成(a || b)&&(c && d)。在jexl中,使用“a”的上下文将评估为true。 – Joseph 2012-12-13 19:02:45
仅供参考:我试着用'(a || b)&&(c && d)'表达的例子,它似乎是固定的。只是'一'评估为'假',这是正确的。 – membersound 2013-01-17 15:26:25
尝试JANINO http://docs.codehaus.org/display/JANINO/Home 这是非常简单的使用,如(从http://docs.codehaus.org/display/JANINO/Basic拍摄):
你可以试试这个库https://github.com/Shy-Ta/expression-evaluator-demo - 阅读我有很多例子。该库使用java和groovy。
除了支持这个用例外,它还支持很多其他类似excel的函数。此外,添加新功能非常简单,如示例中所示。
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();
+1这是一个如何使用它的好例子。 http://commons.apache.org/jexl/reference/examples.html – blak3r 2010-06-17 17:05:21