WARNING : Using eval
is dangerous. Be very careful with it, or, better yet, find an alternative without.
That being said, you could define a regex to check if the string looks like something you'd like to eval
. For example, anything with only numbers, spaces and mathematical operators could be deemed safe:
import re
l = ['hallo', 'hallo\n', '\x00' * 1, '100', 100, '400 + 2', '400 + - ', 400 + 2]
def string_or_expression(something):
if isinstance(something, str):
expression = re.compile('\A[\d\.\-\+\*\/ ]+\Z')
if expression.match(something):
try:
return eval(something)
except:
return something
return something
print([string_or_expression(s) for s in l])
# ['hallo', 'hallo\n', '\x00', 100, 100, 402, '400 + - ', 402]
With Python3, you might use ast.literal_eval
, which might be a little less dangerous than a plain eval
:
import re
import ast
l = ['hallo', 'hallo\n', '\x00' * 1, '100', 100, '400 + 2', '400 + - ', 400 + 2]
def string_or_expression(something):
if isinstance(something,str):
expression = re.compile('\A[\d\.\-\+\*\/ ]+\Z')
if expression.match(something):
try:
return ast.literal_eval(something)
except:
return something
return something
print([string_or_expression(s) for s in l])
# ['hallo', 'hallo\n', '\x00', 100, 100, 402, '400 + - ', 402]
Yet another alternative would be to use @poke's "expression evaluation algorithm", since literal_eval
doesn't understand '2 * 3'
.
Finally, even a "safe" expression like '2**2**2**2**2**2**2**2**2**2'
could bring your server down.