Reputation: 219
Is there an easy way to take a String such as "5*4" and return 20?
Upvotes: 5
Views: 6385
Reputation: 41222
You probably looking for something like JbcParser - Math Parser for Java.
Upvotes: 3
Reputation: 2197
Sounds like you should check out JEXL (Java Expression Language)
It is very easy to use; for example, the solution to your problem is:
public static void main(String[] args) {
long a = 5;
long b = 4;
String theExpression = "a * b";
JexlEngine jexl = new JexlEngine();
Expression e = jexl.createExpression(theExpression);
JexlContext context = new MapContext();
context.set("a", a);
context.set("b", b);
Long result = (Long) e.evaluate(context);
System.out.println("The answer : " + result);
}
Alternatively you could use the following if the string is read in directly:
public static void main(String[] args) {
JexlEngine jexl = new JexlEngine();
Expression e = jexl.createExpression("5 * 4");
Integer result = (Integer) e.evaluate(null);
System.out.println("The answer : " + result);
}
Upvotes: 2
Reputation: 274602
I have used JEval in the past and have found it quite easy and intuitive. Here is a code snippet:
import net.sourceforge.jeval.EvaluationException;
import net.sourceforge.jeval.Evaluator;
public class Main {
public static void main(String[] args) {
try {
System.out.println(new Evaluator().evaluate("5+4*3"));
}
catch (EvaluationException e) {
e.printStackTrace();
}
}
}
Upvotes: 1
Reputation: 346290
The most simple way would be to use the Rhino JavaScript engine available with the JRE 6 standard API.
Edit: as per the comments, if the strings are user-supplied, this could be a potential security hole. Be sure to filter out everything except digits, braces and mathematical operators.
Upvotes: 6
Reputation: 29680
You can also use BeanShell.
It is actually more a Java source interpreter, but recently I used it to evaluate some expressions containing variables (only the eval
method is using BeanShell, the rest is for preparing the output):
import bsh.EvalError;
import bsh.Interpreter;
public class EVAL {
private static final String FORMAT = "%-5s | %-5s | %-5s | %s%n";
public static void main(String[] args) {
tabela("((a && b)||c)");
tabela("a ? (b || c) : (b && c)");
tabela("(a?1:0) + (b?1:0) + (c?1:0) >= 2");
}
private static void tabela(String expressao) {
System.out.printf(FORMAT, " a ", " b ", " c ", expressao);
System.out.printf(FORMAT, "-----", "-----", "-----", expressao.replaceAll(".", "-"));
try {
for (int i = 0; i < 8; i++) {
boolean a = (i & (1<<2)) != 0;
boolean b = (i & (1<<1)) != 0;
boolean c = (i & (1<<0)) != 0;
boolean r = eval(expressao, a, b, c);
System.out.printf(FORMAT, a, b, c, r);
}
} catch (EvalError ex) {
ex.printStackTrace();
}
System.out.println();
System.out.println();
}
private static boolean eval(String expressao, boolean a, boolean b, boolean c) throws EvalError {
Interpreter inter = new Interpreter();
inter.set("a", a);
inter.set("b", b);
inter.set("c", c);
Object resultado = inter.eval(expressao);
return (Boolean) resultado;
}
}
results:
a | b | c | ((a && b)||c)
----- | ----- | ----- | -------------
false | false | false | false
false | false | true | true
false | true | false | false
false | true | true | true
true | false | false | false
true | false | true | true
true | true | false | true
true | true | true | true
a | b | c | a ? (b || c) : (b && c)
----- | ----- | ----- | -----------------------
false | false | false | false
false | false | true | false
false | true | false | false
false | true | true | true
true | false | false | false
true | false | true | true
true | true | false | true
true | true | true | true
a | b | c | (a?1:0) + (b?1:0) + (c?1:0) >= 2
----- | ----- | ----- | --------------------------------
false | false | false | false
false | false | true | false
false | true | false | false
false | true | true | true
true | false | false | false
true | false | true | true
true | true | false | true
true | true | true | true
Upvotes: 1
Reputation: 949
More details about expression evaluation can be found at:
Algorithms in Java, Volume 1, Parts 1-4
Upvotes: 2
Reputation: 3666
I have googled a bit and found that one here. Its not exactly what you need, but maybe it helps depsite of that.
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class ScriptDemo {
public static void main(String[] args) {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
engine.put("a", 1);
engine.put("b", 2);
try {
String expression = "(a + b) > 2";
Object result = engine.eval(expression);
System.out.println(expression+" ? "+result);
} catch(ScriptException se) {
se.printStackTrace();
}
}
}
Upvotes: 2
Reputation: 55448
I don't know which are the best out there but there are "mathematical expressions evaluator" packages.
check out Java Math Expression Evaluator (one file source code included)
Example use from site:
java -cp meval.jar com.primalworld.math.MathEvaluator -cos(0)*(1+2)
java -cp meval.jar com.primalworld.math.MathEvaluator .05*200+3.01
Upvotes: 3
Reputation: 313
You could try parsing it yourself by using Integer.parseInt() and using a switch() statement to find the operators.
You could also try using javax.script.ScriptEngine; for more information see http://forums.sun.com/thread.jspa?threadID=5144807.
Upvotes: 1
Reputation: 43159
You are best off using a library for this. Janino has the ability to evaluate arbitrary Java expressions like the ones you specify, and more besides.
Check out the ExpressionEvaluator example.
Upvotes: 1