概述
本问题已经有最佳答案,请猛点这里访问。
Java中有没有一种方法可以从以下数学表达式获取结果:
String code ="5+4*(7-15)";
另一方面,解析算术表达式的最佳方法是什么?
您可以将其传递给BeanShell bsh.Interpreter,如下所示:
Interpreter interpreter = new Interpreter();
interpreter.eval("result = 5+4*(7-15)");
System.out.println(interpreter.get("result"));
您将要确保评估的字符串来自受信任的来源,并采取通常的预防措施,否则,它将立即起作用。
如果您想采用更复杂(但更安全)的方法,则可以使用ANTLR(我怀疑这是一个数学语法的起点),然后自己实际编译/解释该语句。
好主意,但是对于不受信任的输入却有问题,因为它会允许"脚本注入"(请参阅??我的其他评论)。
@sleske:是的,如果用户输入了字符串,您肯定要小心注入攻击。
这个库真是太好了!
现在也可以使用内置的JavaScript(Rhino)解释器。尽管获得评估似乎更为复杂。而且仍然存在安全风险...
@PhiLho:BeanShell只是我几年前使用的东西,但我同意基于javax.script API(我认为Rhino是)的东西会更好。
+1作为beanshell,是JRE的一部分
如果表达式为" 2/3",这将返回什么?它会像Java一样返回0吗?您可以在前面放一个打字机,但是"(2/3)+(1/2)"呢?
尝试使用beanshell ...如何保证结果始终为DOUBLE类型?
我最近开发了一个表达式解析器,并根据apache许可发布了它。您可以在http://projects.congrace.de/exp4j/index.html上获取它
希望能有所帮助
美观,易于使用,非常适合我的需求。
我不会使用它,因为我实际上需要在整个应用程序中(从配置文件中)解析一个表达式,但是如果我有更多无法解决的需求,我肯定会使用它!我刚刚看了一下,它看起来很棒(甚至支持自定义功能!)。做得好!
您可以使用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
也许有更好的方法,但这是可行的。
谢谢,我不想在我真的不需要时添加依赖项:D
@shbi:它不是外部库,它是内置的javax.script.*
理解了,但是由于此表达式是从外部文件读取的,因此,JS引擎无法评估任意代码。
可能不是您希望的那样简单!
但是,也许您可??以使用javax.script.ScriptEngine并将字符串视为ECMAScript表达式,例如?
看一下:Java平台的脚本。
那是相当危险的,因为它将允许"脚本注入"(类似于SQL注入)。请谨慎操作。
好点子。我想这取决于表达式的来源。
可以使用正则表达式从输入字符串中去除所有"非数学"字符。这样可以保护应用程序免受脚本注入吗? (不打算使用它,只是碰到它,这让我感到好奇)
没有内置的方法可以做到这一点。但是您可以使用许多可用的开源计算器之一。
最近,我使用了非常成熟的数学表达式解析器库(开源),为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();
示例4-用户定义的参数和常量
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支持的Scalar Calculator应用程序。
最好的祝福
LK
Java SDK中没有直接支持执行此操作。
您要么必须自己实现(可能使用诸如JavaCC之类的解析器生成器),要么使用现有的库。
一种选择是JEP(商业),另一种是JEval(免费软件)。
您可以使用该项目
如何使用:
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));
有一个叫做Formula4j的商业工具可以完成这项工作。
为了使用示例表达式,可以使用公式4j对其进行评估:
Formula formula = new Formula("5+4*(7-15)");
Decimal answer = formula.getAnswer(); //-27
public static int calc(String string){
int result=0;
String numbers="0123456789";
String operations="+-/*";
for (int i=0;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;
}
即使使用问题中的简单示例,这也将失败。
不过对我来说效果很好。
可能为您工作,但不回答问题。
总有一种更好的做某事的方法-没有任何事情的最佳方法。希望您会发现它有用。
这将在a + b * c处失败,此代码中的运算符之间没有优先级...
最后
以上就是着急歌曲为你收集整理的jeval 公式_关于Java:如何解析以字符串形式给出的数学表达式并返回数字?的全部内容,希望文章能够帮你解决jeval 公式_关于Java:如何解析以字符串形式给出的数学表达式并返回数字?所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复