2013-04-13 208 views
3

如何在不使用eval的情况下评估数学字符串?红宝石评估没有评估?

实施例:

mathstring = "3+3" 

无论如何,可以在不使用eval进行评价?

也许用正则表达式..?

回答

6

你必须或者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 - 你可以看看其他的答案太)

+0

真棒,这完美的作品。 – Tommy

0

当然 - 你只是想用某种方法解析表达式,而不是使用纯粹的Ruby解释器。

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

或者,它可能不会是难写自己的解析器。 (不是说我已经认真地尝试过 - 我可能完全是废话。)

+0

是否可以用正则表达式来实现?像gsub一样? – Tommy

2

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

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

你有3种选择:

  1. 在我的真实想法最好 - 解析它以逆波兰式,然后分析它作为方程
  2. 至于你说的使用正则表达式
  3. 最快,但很危险,致电eval但不是Kernel#eval

    RubyVM::InstructionSequence.new(mathstring).eval 
    
0

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

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