tags:

views:

66

answers:

2

I'm trying to take a string which is a simple math expression, remove all spaces, remove all duplicate operators, convert to single digit numbers, and then evaluate.

For example, an string like "2 7+*3*95" should be converted to "2+3*9" and then evaluated as 29.

Here's what I have so far:

expression.slice!(/ /) # Remove whitespace
expression.slice!(/\A([\+\-\*\/]+)/) # Remove operators from the beginning
expression.squeeze!("0123456789") # Single digit numbers (doesn't work)
expression.squeeze!("+-*/") # Removes duplicate operators (doesn't work)
expression.slice!(/([\+\-\*\/]+)\Z/) # Removes operators from the end

puts eval expression

Unfortunately this doesn't make single digit numbers nor remove duplicate operators quite like I expected. Any ideas?

+2  A: 
"2 7+*3*95".gsub(/([0-9])[0-9 ]*/, '\1').gsub(/([\+\*\/\-])[ +\*\/\-]+/, '\1')

The first regex handles the single-digit thing and the second handles repeat operators. You could probably condense it into a single regex if you really wanted to.

This works for a quick-and-dirty solution, but you might be better served by a proper parser.

zenazn
FYI, doesn't remove whitespace from the beginning of the expression. Might be simpler and easier to understand if you had a `.gsub(/\s*/, '')` to start?
kejadlen
A: 
DATA.each { |expr| 
    expr.gsub!(%r'\s+', '')
    expr.gsub!(%r'([*/+-])[*/+-]+',  '\1')
    expr.gsub!(%r'(\d)\d+', '\1')
    expr.sub!(%r'\A[*/+-]+', '')
    expr.sub!(%r'[*/+-]+\Z', '')
    puts expr + ' = ' + eval(expr).to_s
}

__END__
2 7+*3*95
+-2 888+*3*95+8*-2/+435+-
FM
I don't know what the line "break unless expr =~ /\S/" but the rest works great, thanks.
stevenheidel