2009-11-15 6 views
10

Javaでブール式を評価する方法が比較的簡単です(パーザを書く場合と比べて)、JEPライブラリを使用したくありません。Javaでのブール式の評価

私は(x > 4 || x < 8 && p > 6)のような文字列式を持っています。私の目的は、変数を値で置き換えることです。

この表現を評価する方法はありますか?

これはどんなレベルでも深いことができるので、パーサの作成は非常に複雑になることに注意してください。

答えて

6

あなたはJava6でスクリプトエンジンを使用してScalaRubyPythonGroovy、そしてJavascriptなどの人気のスクリプト言語のいずれかを選択することができます。あなたがしなければならないことは、あなたが評価したい表現が正しい言語であることを確認することです。 Groovyはおそらく最も簡単で、最もよく統合されます。

一般的なスプレッドシートアプリケーションの数式/計算列とよく似た機能を提供するために、このメソッドを使用しました。

0

JUELは、明示的にJSPに結びつけずにJavaの統一表現言語の実装を提供します。 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

0

http://lts.online.fr/dev/java/math.evaluator/

で入手可能なAPIがあります:

MathEvaluator m = new MathEvaluator("-5-6/(-2) + sqr(15+x)"); 
m.addVariable("x", 15.1d); 
System.out.println(m.getValue()); 
+0

このリンクは、少なくとも作成時には機能していないようです。また、このライブラリは比較演算子をサポートしていますか?OPのような 'boolean'値は尋ねられますか? – andr

0

は、オープンソース実装

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に持っていた1つの問題は、その優先順位付けでした。私が評価する必要があるケースがある| || &&を評価する前に。したがって、上の式は(a || b)&&(c && d)に変わります。 jexlでは、ちょうど 'a'のコンテキストを使用するとtrueと評価されます。 – Joseph

+0

ちょうど参照のために:あなたの式 '(a || b)&&(c && d)'で例を試しましたが、修正されているようです。ちょうど「a」は「偽」と評価されますが、それは正しいです。 – membersound

0

このライブラリを試すことができますhttps://github.com/Shy-Ta/expression-evaluator-demo - 私にはかなりの数の例があります。ライブラリはjavaとgroovyを使います。

このユースケースをサポートするだけでなく、他の多くの優れた機能もサポートしています。また、この例で示すように、新しい関数を追加するのは非常に簡単です。

 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();