> I have a string input from the user, and want to parse it > to a number, and would like to know how to do it. I > would like to be able to accept arithmetic operations, > like: > > '5+5' > '(4+3)*2' > '5e3/10**3' > > I thought of using eval, which will work, but could lead > to bad security problems (not that it's a big deal in my > app, but still...)
I would use eval, as it does a whole lot of work for little cost. I would simply whitelist stuff with a regexp before passing it to eval(): import re tests = [('1*2', 2),('3+5/2', 5), ('8+5*21', 113),('3.14*2+20', 26.28), ('1/0', 0),('3**3yyp', 27), ('3*//+-p', 0)] exp = r'[^-*/+.eE0-9()]' r = re.compile(exp) print "Using regexp: %s" % exp for test, result in tests: s = r.sub('', test) try: print "%s -> %s = %s (should be %s)"% ( test, s,eval(s), result) except: print "invalid expression: %s" % test You can do more graceful handling of div-by-zero vs. general parsing errors here if you want, but you can get the general idea from this. If you wanted, you could include "i" in the regexp, in case you expect your users to use imaginary numbers. You could also include spaces if you wanted. Simply crank their expression through the r.sub() call to clean it of garbage (you can check and compare them if you want to see if anything was changed in the process). Then pass the results to eval() My early-Saturday-morning thoughts... -tkc -- http://mail.python.org/mailman/listinfo/python-list