我如何在不使用 eval 的情况下评估数学字符串?
例子:
mathstring = "3+3"
无论如何,可以在不使用 eval 的情况下进行评估?
也许正则表达式的东西..?
您必须要么或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 在这里写的那样-您也可以查看其他答案)
我假设您出于安全原因不想使用 eval,并且确实很难正确清理 eval 的输入,但是对于简单的数学表达式,也许您可以检查它是否仅包含数学运算符和数字?
mathstring = "3+3"
puts mathstring[/\A[\d+\-*\/=. ]+\z/] ? eval(mathstring) : "Invalid expression"
=> 6
您有 3 个选项:
最快,但危险,通过调用eval
但不是Kernel#eval
RubyVM::InstructionSequence.new(mathstring).eval
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.)
Dentaku似乎(我还没有使用它)是一个很好的解决方案——它可以让你检查你的(数学和逻辑)表达式,并评估它们。
calculator = Dentaku::Calculator.new
calculator.evaluate('kiwi + 5', kiwi: 2)