如何在Python中解析AND / OR运算符以评估条件字符串

时间:2018-10-08 00:03:53

标签: python expression

如果条件字符串中有比较器AND / OR,例如

A != B AND C > 100

我如何解析此字符串并评估结果,以便以下代码返回false

A = "foo" B = "foo" C = 99  ->  eval("A != B AND C > 100") is false

我使用运算符库进行评估并进行幼稚检查,但是如果看到AND,则需要在使用AND运算符之前在两侧完成评估。有没有更好的方法来进行解析和评估?

import operator
ops = {
    "AND": operator.and_,
    "OR": operator.or_,
    "==": operator.eq,
    "!=": operator.ne,
    "<": operator.lt,
    "<=": operator.le,
    ">": operator.gt,
    ">=": operator.ge 
}
        result = false
        content = string.split(" ")
        for content in contents:
            if content in ops:
                    a = contents[i-1]
                    b = contents[i+1]
                result = ops[content](a, b)
                contents[i+1] = result
            i+=1
        if result is True:
            print("It is true")

1 个答案:

答案 0 :(得分:2)

我没有在其中解析实际的变量,但是它应该能够满足您的要求。它首先计算第0个优先级,然后根据第0个计算第1个优先级,依此类推。我只测试了2个优先级,但我认为它应该对所有人都有效。这是它的功能。

['A', '!=', 'A', 'AND', 'B', '==', 'B']
[False, 'AND', True]
[False]

这里是实际代码:

import operator
ops = {
    "AND": operator.and_,
    "OR": operator.or_,
    "==": operator.eq,
    "!=": operator.ne,
    "<": operator.lt,
    "<=": operator.le,
    ">": operator.gt,
    ">=": operator.ge 
}
prior = {
    "AND": 1,
    "OR": 1,
    "==": 0,
    "!=": 0,
    "<": 0,
    "<=": 0,
    ">": 0,
    ">=": 0
}
maxPrior = 1
def parseEval(string):
    content = string.split()
    for priorMode in range(maxPrior+1):
        print(content)
        subParse = []
        subParse = []
        for ind,cont in enumerate(content):
            if cont in ops:
                priorLev = prior[cont]
                if priorLev <= priorMode:
                    condA = content[ind-1]
                    condB = content[ind+1]
                    subParse.append(ops[cont](condA,condB))
                else:
                    subParse.append(cont)   
        content = subParse
    print(content)
    return subParse[0]
parseEval("A != A OR B == B")

如果需要,可以在函数内部进行操作和执行操作。同样遗憾的是,我应该给那些具有优先权的人起一个更好的名字,因为它听起来像另一个词。对不起,如果给您带来混乱。如果您有任何疑问,请告诉我,我们很乐意为您提供帮助!