5

How could I evaluate at mathematical string without using eval?

Example:

mathstring = "3+3"

Anyway that can be evaluated without using eval?

Maybe something with regex..?

5 Answers 5

7

You must either or eval it, or parse it; and since you don't want to eval:

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

If you want to implement more complex stuff you could use RubyParser (as @LBg wrote here - you could look at other answers too)

Sign up to request clarification or add additional context in comments.

Comments

3

I'm assuming you don't want to use eval because of security reasons, and it is indeed very hard to properly sanitize input for eval, but for simple mathematical expressions perhaps you could just check that it only includes mathematical operators and numbers?

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

1 Comment

this is a better regex than the accepted answer. this regex can check for complex strings like 3 + 4.4/2 * 4 / 5.55555. I would suggest adding parentheses to the range.
1

You have 3 options:

  1. In my honest opinion best - parse it to Reverse Polish Notation and then parse it as equation
  2. As you say use RegExps
  3. Fastest, but dangerous and by calling eval but not Kernel#eval

    RubyVM::InstructionSequence.new(mathstring).eval
    

Comments

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.)

1 Comment

is it possible to do it with regex? like with gsub?
0

Dentaku seems (I haven't used it yet) like a good solution - it lets you check your (mathematical and logical) expressions, and to evaluate them.

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.