【问题标题】:Convert mathematical string to int将数学字符串转换为 int
【发布时间】:2011-03-16 05:42:52
【问题描述】:

有没有一种简单的方法来获取诸如“5*4”之类的字符串并返回 20?

【问题讨论】:

  • @Adeel:不,不是... C# 和 Java 是具有不同库和程序的不同语言。
  • @Adeel - 绝对不是,另一个问题要求 c# 解决方案。

标签: java math operators


【解决方案1】:

最简单的方法是使用 JRE 6 标准 API 提供的 Rhino JavaScript engine

编辑: 根据 cmets,如果字符串是用户提供的,这可能是一个潜在的安全漏洞。请务必过滤掉除数字、大括号和数学运算符之外的所有内容。

【讨论】:

  • 是的……但是除了 JavaScript 引擎之外,它还能做更多的事情。如果您在某些情况下暴露了 Rhino 评估程序,您可能会引入……咳咳……安全问题。
  • 这种事情总是让我想起SQL代码注入漏洞。如果这些字符串来自程序外部(用户、文件、套接字......),为了确保它们不是潜在的安全风险,您可能需要解析它们。好吧,好吧,不完全是-您可能会通过正则表达式检查而侥幸,因为您只关心合法令牌集。并且 Javascript 没有标准的文件操作等,所以无论如何你可能是安全的。仍然 - 这让我很紧张。
  • 嗯——我真的应该在评论之前刷新一下。哦,好吧。
【解决方案2】:

我不知道哪些是最好的,但有“数学表达式评估器”包。

查看Java Math Expression Evaluator(包括one file源代码)

网站使用示例:

java -cp meval.jar com.primalworld.math.MathEvaluator -cos(0)*(1+2)
java -cp meval.jar com.primalworld.math.MathEvaluator .05*200+3.01

【讨论】:

  • 因为我正在为第 5 版开发,所以这个最适合我。
【解决方案3】:

您可能正在寻找类似JbcParser - Math Parser for Java 的东西。

【讨论】:

  • 虽然也许值得指出它不是免费的(在任何一种意义上)。
  • 认真的阿尔乔姆? “This”是一个可怕的链接描述符,回滚我的编辑是完全无知的。
【解决方案4】:

我用谷歌搜索了一下,发现了一个here。它不完全是您所需要的,但也许它会有所帮助。

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

【讨论】:

    【解决方案5】:

    有关表达式评估的更多详细信息,请参见:

    Algorithms in Java, Volume 1, Parts 1-4

    【讨论】:

      【解决方案6】:

      听起来你应该看看JEXL(Java 表达式语言)

      非常容易使用;例如,您的问题的解决方案是:

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

      如果直接读入字符串,您也可以使用以下内容:

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

      【讨论】:

        【解决方案7】:

        您最好为此使用库。 Janino 能够评估任意 Java 表达式,例如您指定的表达式,等等。

        查看ExpressionEvaluator 示例。

        【讨论】:

          【解决方案8】:

          您可以尝试使用 Integer.parseInt() 自己解析它并使用 switch() 语句来查找运算符。

          您也可以尝试使用 javax.script.ScriptEngine;如需更多信息,请参阅http://forums.sun.com/thread.jspa?threadID=5144807

          【讨论】:

          • 如果所有的表达式都是二数一运算符,也许。在现实世界中,你对“5+4*3”有什么期望——我希望是 17 而不是 27,这意味着优先级很重要。优先级解析并不难,但它肯定不是微不足道的。我同意“使用图书馆”的答案。
          【解决方案9】:

          您也可以使用BeanShell
          它实际上更像是一个 Java 源代码解释器,但最近我用它来评估一些包含变量的表达式(只有 eval 方法使用的是 BeanShell,rest 用于准备输出):

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

          结果:

            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
          

          【讨论】:

            【解决方案10】:

            我过去使用过JEval,发现它非常简单直观。这是一个代码sn-p:

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

            【讨论】:

              【解决方案11】:

              还有这个:

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2011-10-02
                • 2011-03-06
                • 1970-01-01
                • 2018-07-05
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多