在Python中操作嵌套的布尔查询字符串

在Python中操作嵌套的布尔查询字符串,python,regex,parsing,nlp,booleanquery,Python,Regex,Parsing,Nlp,Booleanquery,我有这样的字符串布尔查询 queryString= """And( OR(abc,xyz,wxy), AND(AND(xyz,wxy),xzy), XOR(x1,y1, AND(xy,zz)) )""" 目前,我很难按照自己的意愿修改上面的查询字符串 在最后一个XOR中添加另一个ORx3、y3 移除整个ORab

我有这样的字符串布尔查询

   queryString= """And(
                      OR(abc,xyz,wxy),
                      AND(AND(xyz,wxy),xzy),
                      XOR(x1,y1, AND(xy,zz))  
                      )"""
目前,我很难按照自己的意愿修改上面的查询字符串

在最后一个XOR中添加另一个ORx3、y3 移除整个ORabc、xyz、wxy 有理想的输出

   resultQueryString= """And(                        
                            AND(AND(xyz,wxy),xzy),
                            XOR(x1,y1, AND(xy,zz),OR(x3,y3))  
                            )"""
我想,除非我为每个不同的查询提供一个复杂的正则表达式,否则我很难做到这一点

我正在尝试编写一个python函数,该函数将上述字符串布尔查询作为输入并输出一个树数据结构

这样我就可以遍历树并计算或更改查询的任何部分

在上面的例子中,如果我把它作为一棵树,我可以很容易地看到根是和,并遍历/修改其他分支,依此类推。

ast.parse函数似乎几乎完全符合您的要求:

ast.dump(ast.parse("""And(                        
                        AND(AND(xyz,wxy),xzy),
                        XOR(x1,y1, AND(xy,zz),OR(x3,y3))  
                        )""").body[0].value)
Callfunc=Nameid='And',ctx=Load,args=[Callfunc=Nameid='And',ctx=Load,args=[Callfunc=Nameid='And',ctx=Load,args=[Nameid='xyz',ctx=Load,Nameid='wxy',ctx=Load],关键字=[],starargs=None,Nameid='xzy',ctx=Load],关键字=[],starargs=None,kwargs=None,kwargs=None,Callfunc=Nameid='XOR','ctx=Load,args=[Nameid='x1',ctx=Load,Nameid='y1',ctx=Load,Callfunc=Nameid='AND',ctx=Load,ctx=Load,Nameid='xy',ctx=Load,Nameid='zz',ctx=Load],keywords=[],starargs=None,kwargs=None,Callfunc=Nameid='OR',ctx=Load,args=[Nameid='x3',ctx=Load],关键字=[],starargs=None,kwargs=None],关键字=[],starargs=None,kwargs=None,kwargs=None,kwargs=None],关键字=[],starargs=None,kwargs=None

.body[0].值删除了两个毫无意义的抽象层,.dump仅用于输出

下面是对输出执行您请求的转换的代码:

class Filterer(ast.NodeTransformer):
    def visit_Call(self, node):
            name=node.func.id
            if name == "OR" and len(node.args) == 3:
                    return None
            elif name == "XOR":
                    args = [ast.Name("x3",ast.Load()),
                            ast.Name("y3",ast.Load())]
                    func = ast.Name("OR",ast.Load())
                    node.args.append(ast.Call(func, args, [], None, None))
            return self.generic_visit(node)
下面是以您的格式打印结果的代码,除了空白:Python的ast模块中没有用于此目的的内置代码:

class Printer(ast.NodeVisitor):
    def visit_Call(self, node):
            self.visit(node.func)
            print("(",end="")
            comma = False
            for arg in node.args:
                    if comma:
                            print(",",end="")
                    comma=True
                    self.visit(arg)
            print(")",end="")
    def visit_Name(self, node):
            print(node.id,end="")
因此,最终准则将是:


Printer.visitfilter.visitast.parsequeryString

谢谢,您是否也可以编写接受queryString的代码,然后打印所需的输出,如图所示resultQueryString@Watt完成了。打印有点复杂