numeric expression from string?

Tim Chase python.list at tim.thechases.com
Sat Feb 4 10:31:20 EST 2006


> 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









More information about the Python-list mailing list