How to parse a mathematical expression given as a string and return a number?

90,503

Solution 1

You can pass it to a BeanShell bsh.Interpreter, something like this:

Interpreter interpreter = new Interpreter();
interpreter.eval("result = 5+4*(7-15)");
System.out.println(interpreter.get("result"));

You'll want to ensure the string you evaluate is from a trusted source and the usual precautions but otherwise it'll work straight off.

If you want to go a more complicated (but safer) approach you could use ANTLR (that I suspect has a math grammar as a starting point) and actually compile/interpret the statement yourself.

Solution 2

i recently developed a expression parser and released it under the apache license. you can grab it at http://projects.congrace.de/exp4j/index.html

hope that helped

Solution 3

You can use the ScriptEngine class and evaluate it as a javascript string

ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");        
Object result = engine.eval("5+4*(7-15)");

Indeed , yu should know that the result of the following instruction in javascript :

   eval('var aa=5+4*(7-15)')
   aa // -27

There may be a better way, but this one works.

Solution 4

Probably not in as straight forward a manner as you are hoping!

But perhaps you could use a javax.script.ScriptEngine and treat the string as a ECMAScript expression, for example?

Take a look at: Scripting for the Java Platform.

Solution 5

There is no builtin way of doing that. But you can use one of the many many open source calculators available.

Share:
90,503

Related videos on Youtube

Martijn Courteaux
Author by

Martijn Courteaux

I'm writing Java, C/C++ and some Objective-C. I started programming in 2007 (when I was 11). Right now, I'm working on my magnum opus: an iOS, Android, OS X, Linux, Windows game to be released soon on all relevant stores. The game is written in C++ using SDL and OpenGL. A couple of seeds for my name (for java.util.Random, radix 26): 4611686047252874006 -9223372008029289706 -4611685989601901802 28825486102

Updated on November 07, 2020

Comments

  • Martijn Courteaux
    Martijn Courteaux over 3 years

    Is there a way in Java to get the result from this mathematical expression:

    String code = "5+4*(7-15)";
    

    In other hand what's the best way to parse an arithmetic expression?

  • sleske
    sleske over 14 years
    That is rather dangerous, as it would allow "script injection" (similar to SQL injection). Proceed with caution.
  • Andy
    Andy over 14 years
    Good point. I suppose it depends on what the source of the expressions is.
  • sleske
    sleske over 14 years
    Good idea, but problematic with untrusted input, as it would allow "script injection" (see my other comment).
  • Nick Holt
    Nick Holt over 14 years
    @sleske: yeah, you'd certainly have to be careful with injection attacks if the string is user entered.
  • PhiLho
    PhiLho over 14 years
    Can also use built-in JavaScript (Rhino) interpreter now. Although seems more complex to get an eval. And still have a security risk...
  • Nick Holt
    Nick Holt over 14 years
    @PhiLho: BeanShell was just something I used a few years ago, but I agree that something based on the javax.script API (I think Rhino is) would be better.
  • matbrgz
    matbrgz over 14 years
    +1 for beanshell, being part of the JRE
  • dreeves
    dreeves almost 14 years
    What would this return if the expression were "2/3"? Would it return 0 like Java does? You could stick a typecast in front, but then what about "(2/3)+(1/2)"?
  • marcolopes
    marcolopes about 12 years
    Trying to use beanshell... How can i guarantee that the result will always be in DOUBLE type?
  • Kevin Cooper
    Kevin Cooper over 11 years
    Beautiful, incredibly simple to use and works great for my needs.
  • FThompson
    FThompson over 11 years
    A regex could be used to strip all "non-math" characters from the input string. Would that secure the application from script injection? (Not planning on using this, but just came across it and it made me curious)
  • Igor
    Igor about 10 years
    I won't be using this, because I actually need to parse one single expression throughout my application (from a configuration file), but if I had more and couldn't workaround the need, I'd certainly use this! I just had a look at this and it looks amazing (even custom functions are supported!). Great work!
  • Mat
    Mat over 9 years
    This would fail even with the simple example in the question.
  • Semioniy
    Semioniy over 9 years
    Works well for me though.
  • Mat
    Mat over 9 years
    Might work for you, but doesn't answer the question.
  • Semioniy
    Semioniy over 9 years
    There´s always a better way of doing smth - there is no Best way for anything. Hope, you´ll find that useful.
  • shbi
    shbi over 8 years
    Thanks, I prefer not to have to add dependencies when I don't really need to :D
  • Mohsen_Fatemi
    Mohsen_Fatemi over 7 years
    this would fail at a+b*c , there is no priority between operators in this code ...
  • Abdennour TOUMI
    Abdennour TOUMI almost 7 years
    @shbi : it is not an external library, it is built-in javax.script.*
  • shbi
    shbi almost 7 years
    Understood, but since this expression is being read from an external file, JS engine evaluating arbitrary code is not an option.
  • John
    John over 3 years
    I updated the link. The formula4j tool is now open source.