Java 如何解析以字符串形式给出的数学表达式并返回数字?
Java中有没有一种方法可以从这个数学表达式中得到结果:Java 如何解析以字符串形式给出的数学表达式并返回数字?,java,string,parsing,math,expression,Java,String,Parsing,Math,Expression,Java中有没有一种方法可以从这个数学表达式中得到结果: String code = "5+4*(7-15)"; 另一方面,解析算术表达式的最佳方法是什么?没有内置的方法。但是,您可以使用许多可用的方法中的一种。可能没有您希望的那样直接 例如,您可以使用javax.script.ScriptEngine并将字符串视为ECMAScript表达式 请看:。Java SDK中没有对此的直接支持 您要么自己实现它(可能使用诸如JavaCC之类的解析器生成器),要么使用现有的库 一个选项是(商业),另一
String code = "5+4*(7-15)";
另一方面,解析算术表达式的最佳方法是什么?没有内置的方法。但是,您可以使用许多可用的方法中的一种。可能没有您希望的那样直接 例如,您可以使用javax.script.ScriptEngine并将字符串视为ECMAScript表达式
请看:。Java SDK中没有对此的直接支持 您要么自己实现它(可能使用诸如JavaCC之类的解析器生成器),要么使用现有的库 一个选项是(商业),另一个是(自由软件)。您可以将其传递给
bsh.translator
,如下所示:
Interpreter interpreter = new Interpreter();
interpreter.eval("result = 5+4*(7-15)");
System.out.println(interpreter.get("result"));
您需要确保您计算的字符串来自可信的源和通常的预防措施,否则它将立即工作
如果您想采用更复杂(但更安全)的方法,您可以使用(我怀疑它的起点是数学语法)自己编译/解释语句。我最近开发了一个表达式解析器,并在apache许可下发布了它。你可以在
希望这有帮助,有一个开源的工具,叫做做这项工作 以您的示例表达式为例,使用公式4j对其进行如下计算:
公式公式=新公式(“5+4*(7-15)”代码>
Decimal answer=formula.getAnswer()//-27
你可以用这个
如何使用:
double result = 0;
String code = "5+4*(7-15)";
try {
Expr expr = Parser.parse(code);
result = expr.value();
} catch (SyntaxException e) {
e.printStackTrace();
}
System.out.println(String.format("Result: %.04f", result));
您可以使用ScriptEngine类并将其作为javascript字符串进行计算
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
Object result = engine.eval("5+4*(7-15)");
事实上,yu应该知道以下javascript指令的结果:
eval('var aa=5+4*(7-15)')
aa // -27
也许有更好的方法,但这一种有效。公共静态int-calc(String){
public static int calc(String string){
int result=0;
String numbers="0123456789";
String operations="+-/*";
for (int i=0;i<string.length();i++){
if (numbers.contains(string.charAt(i)+"")){
result=result*10+(Integer.parseInt(string.charAt(i)+""));
}
else {
if (string.charAt(i)=='+'){ result+=calc(string.substring(i+1));}
if (string.charAt(i)=='-'){ result-=calc(string.substring(i+1));}
if (string.charAt(i)=='*'){ result*=calc(string.substring(i+1));}
if (string.charAt(i)=='/'){ try{result/=calc(string.substring(i+1));}
catch (ArithmeticException e){
System.err.println("You cannot devide by Zero!");}
}
break;
}
}
return result;
}
int结果=0;
字符串编号=“0123456789”;
字符串操作=“+-/*”;
对于(int i=0;i最近,我使用了非常成熟的数学表达式解析器库,开源,为JAVA和.NET提供了相同的API。库名为mXparser。mXparser提供基本功能(简单公式解析和计算)和更高级的功能(即用户定义的参数、函数)。此外,值得注意的是,mXparser具有丰富的内置数学集合(表示运算符、一元/二元/变量函数、迭代运算符,如求和和和乘积)
请在下面找到一些示例,以便更清楚地了解语法
示例1-简单公式
Expression e = new Expression("2+3");
double v = e.calculate();
示例2-内置函数
Expression e = new Expression("2+sin(3)");
double v = e.calculate();
示例3-内置常量
Expression e = new Expression("2+sin(pi)");
double v = e.calculate();
Argument x = new Argument("x = 5");
Constant a = new Constant("a = 2 + sin(3)");
Expression e = new Expression("a + x^2", x, a);
double v1 = e.calculate();
x.setArgumentValue(10);
double v2 = e.calculate();
示例4-用户定义的参数和常量
Expression e = new Expression("2+sin(pi)");
double v = e.calculate();
Argument x = new Argument("x = 5");
Constant a = new Constant("a = 2 + sin(3)");
Expression e = new Expression("a + x^2", x, a);
double v1 = e.calculate();
x.setArgumentValue(10);
double v2 = e.calculate();
示例5-用户定义函数
Function f = new Function("f(x,y) = x^2 + cos(y)");
Expression e = new Expression("f(10,pi) - 3", f);
double v = e.calculate();
示例6-用户定义的递归
Function factorial = new Function("fact(n) = if( n > 0; n*fact(n-1); 1)");
Expression e = new Expression("fact(10) - 10!", factorial);
double v = e.calculate();
最近发现-如果您想尝试语法(并查看高级用例),可以下载mXparser支持的
致意
LK这是相当危险的,因为它会允许“脚本注入”(类似于SQL注入)。请谨慎行事。这一点很好。我认为这取决于表达式的来源。可以使用正则表达式从输入字符串中删除所有“非数学”字符。这会确保应用程序不受脚本注入的影响吗?(不打算使用这个,但只是偶然发现了它,这让我好奇)好主意,但不受信任的输入会有问题,因为它会允许“脚本注入”(见我的其他评论)。@sleske:是的,如果字符串是用户输入的,你肯定必须小心注入攻击。也可以使用内置JavaScript(Rhino)现在是解释器。虽然评估起来似乎更复杂。但仍然存在安全风险…@PhiLho:BeanShell只是我几年前使用的东西,但我同意基于javax.script
API的东西(我认为Rhino是)会更好。+1对于beanshell,作为JREBeautiful的一部分,非常简单易用,非常适合我的需要。我不会使用它,因为我实际上需要在整个应用程序中解析一个表达式(来自配置文件),但是如果我有更多的,并且不能解决这个问题,我当然会使用它!我刚刚看了一下,它看起来很神奇(甚至支持自定义函数!)。太棒了!即使有问题中的简单示例,这也会失败。但对我来说效果很好。可能对你有用,但不能回答问题。总是有更好的方法来做smth-没有最好的方法。希望,你会发现这很有用。这在a+b*c中会失败,在这段代码中运算符之间没有优先级…谢谢s、 我不希望在不需要添加依赖项的情况下添加依赖项:D@shbi:它不是一个外部库,它是内置的javax.script.*
可以理解,但是由于这个表达式是从外部文件读取的,JS引擎评估任意代码不是一个选项。我更新了链接。formula4j工具现在是开源的。