Évaluation Expression booléenne en Java
-
20-09-2019 - |
Question
Je suis à la recherche d'une relativement simple (par rapport à l'écriture d'un analyseur) façon d'évaluer les expressions booléennes en Java, et je ne veux pas utiliser la bibliothèque JEP.
J'ai une expression de chaîne comme: (x > 4 || x < 8 && p > 6)
et mon objectif est de remplacer les variables par les valeurs
Y at-il un moyen par lequel je peux évaluer cette expression?
Gardez à l'esprit que cela peut être un niveau profond écrit donc un analyseur serait très complexe.
La solution
Vous pouvez utiliser le moteur de script dans java6 et choisissez l'une des langages de script populaires comme Scala , Ruby , Python , < a href = "http://groovy.codehaus.org/" rel = "nofollow noreferrer"> Groovy et Javascript . Que tout ce que vous avez à faire est assurez-vous que l'expression que vous voulez évaluer est dans la bonne langue. Groovy est probablement le plus facile et intégrera le mieux.
Je l'ai utilisé cette méthode avec succès pour une fonctionnalité qui offre des capacités beaucoup plus comme une formule / colonne calculée dans une application de tableur populaire.
Autres conseils
Utiliser Apache Commons Jexl; ce qui est exactement conçu pour une telle exigence.
Utilisation jexl ( http://commons.apache.org/jexl/ ), vous pouvez accomplir ceci comme cela
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));
Voici les dernières ressources pour cadre d'évaluation de l'expression
La page d'information est à http://expressionoasis.vedantatree.com/
JUEL fournit une implémentation de la langue d'expression unifiée Java sans être explicitement lié à JSP. Voici son Guide de démarrage rapide , l'évaluation de l'expression (# 3 sur cette page) est la partie qui vous intéresse.
Vous pouvez également Spring 3.0 fournit son propre (quoique un peu similaire) langue d'expression. Cette option n'a de sens que si vous utilisez déjà Spring, bien -. Je ne le tirer en juste pour EL
http://code.google.com/p/xpressionengine/ implémentation open source
J'ai trouvé les bibliothèques énumérées ici trop compliqué pour mes besoins. Je fini par utiliser FScript: http://fscript.sourceforge.net/
Il y a une API disponible à http://lts.online.fr/ dev / java / math.evaluator /
Exemple:
MathEvaluator m = new MathEvaluator("-5-6/(-2) + sqr(15+x)");
m.addVariable("x", 15.1d);
System.out.println( m.getValue() );
essayer Janino http://docs.codehaus.org/display/JANINO/Home Il est très simple à utiliser, par exemple (extrait de http://docs.codehaus.org/display/JANINO / de base):
// 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);
Vous pouvez essayer cette bibliothèque https://github.com/Shy-Ta/expression -evaluator-démo - le me lire a un bon nombre d'exemples. La bibliothèque utilise java et groovy.
En plus de soutenir ce cas d'utilisation, il prend en charge aussi beaucoup d'autres fonctions comme exceller. En outre, il est très simple d'ajouter de nouvelles fonctions comme le montre l'exemple.
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();