5

我如何在不使用 eval 的情况下评估数学字符串?

例子:

mathstring = "3+3"

无论如何,可以在不使用 eval 的情况下进行评估?

也许正则表达式的东西..?

4

5 回答 5

7

您必须要么或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 在这里写的那样-您也可以查看其他答案)

于 2013-04-13T23:52:18.623 回答
3

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

mathstring = "3+3"
puts mathstring[/\A[\d+\-*\/=. ]+\z/] ? eval(mathstring) : "Invalid expression"
=> 6
于 2013-04-14T00:01:04.693 回答
1

您有 3 个选项:

  1. 老实说,最好 - 将其解析为反向波兰表示法,然后将其解析为等式
  2. 正如你所说,使用 RegExps
  3. 最快,但危险,通过调用eval但不是Kernel#eval

    RubyVM::InstructionSequence.new(mathstring).eval
    
于 2013-04-14T00:01:30.063 回答
0

Sure--you'd just want to somehow parse the expression using something other than the bare Ruby interpreter.

There appear to be some good options here: https://www.ruby-toolbox.com/search?q=math

Alternatively, it probably wouldn't be that hard to write your own parser. (Not that I've seriously tried--I could be totally full of crap.)

于 2013-04-13T23:46:59.470 回答
0

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

calculator = Dentaku::Calculator.new
calculator.evaluate('kiwi + 5', kiwi: 2)
于 2016-03-14T19:33:56.800 回答