Булева оценка выражений в Java
Я ищу сравнительно простой (по сравнению с написанием парсера) способ оценки булевых выражений в Java, и я не хочу использовать библиотеку JEP.
У меня есть строковое выражение вроде: (x > 4 || x < 8 && p > 6)
, и моя цель - заменить переменные значениями.
Есть ли способ оценить это выражение?
Имейте в виду, что это может быть любой уровень, поэтому писать парсер будет очень сложно.
Ответы
Ответ 1
Вы можете использовать механизм сценариев в Java6 и выбрать любой из популярных языков сценариев, например Scala, Ruby, Python, Groovy и Javascript. Чем все, что вам нужно сделать, это убедиться, что выражение, которое вы хотите оценить, находится на правильном языке. Groovy, вероятно, самый простой и будет лучше интегрироваться.
Я успешно использовал этот метод для функций, предлагающих функции, подобно столбцу формулы/расчета в популярном приложении для электронных таблиц.
Ответ 2
Использовать Apache Commons Jexl; который точно предназначен для такого требования.
http://commons.apache.org/jexl/
Ответ 3
Используя 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));
Ответ 4
Вот последние ресурсы для рамки оценки выражений
Информационная страница находится на http://expressionoasis.vedantatree.com/
Ответ 5
JUEL обеспечивает реализацию Java Unified Expression Language без явной привязки к JSP. Здесь его Краткое руководство, оценка выражения (# 3 на этой странице) - это часть, которую вы заинтересовали.
В качестве альтернативы Spring 3.0 предоставляет свой собственный (хотя и несколько похожий) язык выражений. Этот параметр имеет смысл только в том случае, если вы уже используете Spring, хотя я бы не вытащил его только для EL.
Ответ 6
Существует 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() );
Ответ 7
Попробуйте http://code.google.com/p/xpressionengine/ для реализации с открытым исходным кодом
Ответ 8
Я нашел библиотеки, перечисленные здесь слишком сложными для моих нужд. Я закончил использование Fscript:
http://fscript.sourceforge.net/
Ответ 9
попробуйте Джанино
http://docs.codehaus.org/display/JANINO/Home
Его очень просто использовать, например (взято из http://docs.codehaus.org/display/JANINO/Basic):
// 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);
Ответ 10
Вы можете попробовать эту библиотеку 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();