【问题标题】:Ruby evaluate without eval?Ruby 评估没有评估?
【发布时间】:2016-03-15 05:44:50
【问题描述】:

如何在不使用 eval 的情况下计算数学字符串?

例子:

mathstring = "3+3"

不使用 eval 就可以求值吗?

也许有一些正则表达式..?

【问题讨论】:

    标签: ruby eval


    【解决方案1】:

    你必须要么eval它,要么解析它;既然你不想eval:

    mathstring = '3+3'
    i, op, j = mathstring.scan(/(\d+)([+\-*\/])(\d+)/)[0] #=> ["3", "+", "3"]
    i.to_i.send op, j.to_i #=> 6
    

    如果你想实现更复杂的东西,你可以使用RubyParser(正如@LBg 写的here - 你也可以看看其他答案)

    【讨论】:

      【解决方案2】:

      我假设您出于安全原因不想使用 eval,并且确实很难正确清理 eval 的输入,但是对于简单的数学表达式,也许您可​​以检查它是否仅包含数学运算符和数字?

      mathstring = "3+3"
      puts mathstring[/\A[\d+\-*\/=. ]+\z/] ? eval(mathstring) : "Invalid expression"
      => 6
      

      【讨论】:

      • 这是一个比接受的答案更好的正则表达式。这个正则表达式可以检查像 3 + 4.4/2 * 4 / 5.55555 这样的复杂字符串。我建议在范围内添加括号。
      【解决方案3】:

      您有 3 个选项:

      1. 在我看来最好 - 将其解析为反向波兰表示法,然后将其解析为方程式
      2. 如你所说,使用正则表达式
      3. 最快,但很危险,通过调用eval 而不是Kernel#eval

        RubyVM::InstructionSequence.new(mathstring).eval
        

      【讨论】:

        【解决方案4】:

        当然——你只是想以某种方式使用裸露的 Ruby 解释器以外的东西来解析表达式。

        这里似乎有一些不错的选择:https://www.ruby-toolbox.com/search?q=math

        另外,编写自己的解析器可能不会那么困难。 (我没有认真尝试过——我可能完全是废话。)

        【讨论】:

        • 可以用正则表达式吗?喜欢 gsub 吗?
        【解决方案5】:

        Dentaku 似乎(我还没有使用它)是一个很好的解决方案——它可以让你检查你的(数学和逻辑)表达式,并评估它们。

        calculator = Dentaku::Calculator.new
        calculator.evaluate('kiwi + 5', kiwi: 2)
        

        【讨论】:

          猜你喜欢
          • 2016-08-19
          • 2011-03-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-02-08
          • 2016-08-25
          相关资源
          最近更新 更多