2009-11-15 185 views
10

我正在尋找一種相對簡單(與編寫解析器相比)的方式來評估Java中的布爾表達式,並且我不想使用JEP庫。Java中的布爾表達式評估

我有一個字符串表達式,如:(x > 4 || x < 8 && p > 6),我的目標是用值替換變量。

有沒有一種方法可以評估這個表達式?

請記住,這可以是任何深度級別,因此編寫解析器將非常複雜。

回答

6

您可以使用腳本引擎中Java6和選擇任何流行的腳本語言一樣ScalaRubyPythonGroovyJavascript。比你所要做的是確保你想評估的表達是用正確的語言。 Groovy可能是最簡單的,並將整合最好。

我已經成功地使用這種方法提供功能,非常類似於流行的電子表格應用程序中的公式/計算列。

0

JUEL提供了Java的統一表達式語言的實現,而不必明確地綁定到JSP。這是它的Quick Start guide,表達式評估(該頁上的#3)是您感興趣的部分。

或者,Spring 3.0提供了它自己的(儘管有點類似)表達式語言。這個選項只有在你已經使用Spring的時候纔有意義 - 不過我不會爲了EL而使用它。

14

使用Apache Commons Jexl;這正是爲這樣的要求而設計的。

http://commons.apache.org/jexl/

+1

+1這是一個如何使用它的好例子。 http://commons.apache.org/jexl/reference/examples.html – blak3r 2010-06-17 17:05:21

0

有可用的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()); 
+0

這個鏈接似乎沒有工作,至少在撰寫本文時。此外,這個庫是否支持比較運算符和像OP那樣的布爾值? – andr 2012-12-31 11:18:22

7

使用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)); 
+0

我與jexl有一個問題是它的優先級。我有一個需要評估||的案例在評估&&之前。所以上面的表達式變成(a || b)&&(c && d)。在jexl中,使用「a」的上下文將評估爲true。 – Joseph 2012-12-13 19:02:45

+0

僅供參考:我試着用'(a || b)&&(c && d)'表達的例子,它似乎是固定的。只是'一'評估爲'假',這是正確的。 – membersound 2013-01-17 15:26:25

0

你可以試試這個庫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();