Python中的安全表达式解析器

时间:2010-08-27 08:17:45

标签: python parsing

如何让用户以安全的方式执行数学表达式? 我需要编写完整的解析器吗?

是否有像ast.literal_eval()这样的东西,但对于表达式?

5 个答案:

答案 0 :(得分:10)

Pyparsing examples page列出了几个表达式解析器:

http://pyparsing.wikispaces.com/file/view/fourFn.py - 使用pyparsing的传统算术中缀表示法解析器/求值器实现(尽管它的名称,这实际上是5函数算法,加上几个trig函数)

http://pyparsing.wikispaces.com/file/view/simpleBool.py - 布尔中缀表示法解析器/求值程序,使用pyparsing辅助方法operatorPrecedence,简化了中缀运算符表示法的定义

http://pyparsing.wikispaces.com/file/view/simpleArith.py http://pyparsing.wikispaces.com/file/view/eval_arith.py - 一对使用operatorPrecedence重铸fourFn.py的示例。第一个只解析并返回一个解析树,第二个添加评估逻辑。

答案 1 :(得分:3)

你想要什么样的表达方式?变量赋值?功能评估?

SymPy旨在成为一个成熟的Python CAS。

答案 2 :(得分:1)

几周前我做了类似的事情,但是对于逻辑表达式(或者,而不是,比较,括号等)。我是使用Ply解析器完成的。我创建了简单的词法分析器和解析器。解析器生成AST树,后来用于执行计算。以这种方式执行此操作可以让您完全控制用户输入的内容,因为只会解析与语法兼容的表达式。

答案 3 :(得分:0)

是。即使表达式有等效的ast.literal_eval(),Python表达式也可以是很多东西,而不仅仅是纯数学表达式,例如任意函数调用。

如果在一些开源模块中已经有一个很好的数学表达式解析器/求值器,那就不会让我感到惊讶,但如果没有,那么编写自己的一个很容易。

答案 4 :(得分:-1)

数学函数将由数字和标点字符组成,如果您允许有理数的科学记数法,可能是“E”或“e”,如果您允许/提供特定数学,则唯一(其他)合法使用字母字符将是功能(例如stddev)。因此,沿着字符串运行字母字符应该是微不足道的,并检查下一个小点是不可疑的,然后只需在try / except块中评估字符串。

回复此回复收到的评论......我同意这种做法正在起火。尽管如此,这并不意味着它无法安全地完成。我是python的新手(< 2个月),所以可能不知道这个易受攻击的变通方法(当然新的Python版本总是会让代码在将来变得不安全),但是 - 它的价值很小(主要是我自己的娱乐) - 这是我对它的抨击:

def evalMaths(s):
    i = 0
    while i < len(s):
        while s[i].isalpha() and i < len(s):
            idn += s[i]
            i += 1
        if (idn and idn != 'e' and idn != 'abs' and idn != 'round'):
            raise Exception("you naughty boy: don't " + repr(idn))
        else:
            i += 1
    return eval(s)

我会非常有兴趣听听它是否/如何被规避...(^ _^)顺便说一句/我知道你可以调用像abs2783或_983这样的函数 - 如果它们存在,但它们不会。我的意思是实用的东西。

事实上,如果有人可以这样做,我会用200赏金创建一个问题并接受他们的回答。