尝试构建逻辑解析器时出错

时间:2019-08-01 06:57:38

标签: python python-3.x dictionary

所以我将这些字符串存储在数据库中,我想将它们转换为python表达式,以便将它们与if语句一起使用。我将这些字符串存储到列表中并循环遍历它们。 例如:

string = "#apple and @banana or @grapes"

我可以通过将#替换为“ a ==”并将@替换为“ b ==”来转换此字符串:

if a == apple and b == banana or b == grapes

哈希是指 @表示b

但是当我使用eval时,它会引发错误“苹果未定义”,因为苹果不在引号中。所以我想要的是这个

if a == "apple" and b == "banana" or b == "grapes"

有什么办法可以做到这一点? 存储在数据库中的字符串可以具有任何类型的格式,可以具有多个和/或条件。

几个例子:

string[0] = "#apple and @banana or @grapes"
string[1] = "#apple or @banana and @grapes"
string[2] = "#apple and @banana and @grapes"

还有其他条件没有满足的条件

谢谢

2 个答案:

答案 0 :(得分:0)

我不确定您在这里要问什么,但是可以使用replacesplit函数:

string = "#apple and #banana"
fruits = string.replace("#", "").split("and")
if a == fruits[0] and b == fruits[1]:

希望这会有所帮助

答案 1 :(得分:0)

如果我正确理解,您正在尝试设置某种逻辑解析器-您想评估该表达式是否可以为真。

@word or @otherword

始终为真,因为例如可以用@=word来满足,但是

@word and @otherword

不是,因为不可能满足此要求。您使用的方式是使用Python的内置解释器,但是您似乎在“补足”了变量ab,它们不存在。只是给您一个这样的解析器的入门,这是一个错误的实现:

from itertools import product
def test(string):
    var_dict   = {}
    word_dict  = {}
    cur_var    = ord('a')
    expression = []
    for i,w in enumerate(string.split()):
        if not i%2:
            if w[0] not in var_dict:
                var_dict[w[0]] = chr(cur_var)
                word_dict[var_dict[w[0]]] = []
                cur_var += 1
            word_dict[var_dict[w[0]]].append(w[1:])
            expression.append('{}=="{}"'.format(var_dict[w[0]],w[1:]))
        else: expression.append(w)
    expression = ' '.join(expression)

    result = {}
    for combination in product(
        *([(v,w) for w in word_dict[v]] for v in word_dict)): 
        exec(';'.join('{}="{}"'.format(v,w) for v,w in combination)+';value='+expression,globals(),result)
        if result['value']: return True
    return False

除了不检查字符串是否有效外,这也不是什么好事,而是一个开始掌握所要内容的地方。

这是在第一个循环中创建表达式,同时保存将单词(w[0])的前几个字符映射到从a到z命名的变量的哈希(如果您想要更多,则需要做的比cur_var+=1)。还将每个这样的变量映射到原始表达式(word_dict)中分配给它的所有单词。

第二个循环运行一个非常糟糕的算法-product会给变量和匹配的单词提供所有可能的配对,并且我会在exec命令中迭代每个组合并为假变量分配单词。有很多理由可以避免使用exec,但这对于设置变量最简单。如果找到满足表达式的组合,则返回True,否则返回False。如果要分配内容(或用于eval等),则不能使用if,for,while

尽管可以编写更长的代码,但编写自己的逻辑解析器以读取字符串不能大大改善此问题。

#Evaluted as (#apple and @banana) or @grapes) by Python - only #=apple @=banana satisfies this.
>>> test("#apple and @banana or @grapes")
True
#Evaluted as #apple or (@banana and @grapes) by Python - all combinations satisfy this as @ does not matter.
>>> test("#apple or @banana and @grapes") 
True
#demands both @=banana and @=grapes - impossible.
>>> test("#apple and @banana and @grapes")
False