简体   繁体   中英

Convert mathematical string to int

是否有一种简单的方法来取一个字符串,如“5 * 4”并返回20?

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.

你可能正在寻找像JbcParser - Math Parser for Java这样的东西。

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

More details about expression evaluation can be found at:

Algorithms in Java, Volume 1, Parts 1-4

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

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

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.

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 .

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

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

There is also this one:

https://eval.dev.java.net/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM