【Python】通过构造树结构解析查询条件
背景概述
最近遇到了需要解析类似这种东西的需求
名称,摘要,主权项+=(育种 or 选育 or (培育 and (种 or 苗)) or 育苗) and (分类号=(A01K61% or A01G33% or A01K63%) or (名称,摘要,主权项+=(刺参 or 海星 or 乌贼 or 扇贝 or 文蛤 or 鲍鱼 or 蛤仔 or 贻贝 or 魁蚶 or 毛蚶 or 缢蛏 or (藻 not (海藻粉 or 硅藻土 or 藻酸)) or 蟹 or 虾 or 水母 or 海螺 or 龟 or (鱼 not (鱼腥草 or 鱼粉 or 鱼雷 or 鱼眼镜头)) or 鲨 or 鲸 or 豚 or 海蛇 or 海狮 or 海豹 or 鳗 or 鲷 or 魨 or 鲆 or 海参 or 海带 or 海胆 or 水产 or 海鲜 or 大鲵 or 贝类 or 种贝 or 养鱼 or 水生动物 or 螺类 or 海蜗牛 or 紫螺 or 钉螺 or 福寿螺 or 角螺 or 田螺 or 玉螺 or 泥螺 or 马蹄螺 or 蝾螺 or 脉红螺 or 香螺 or 金丝螺 or 海螂 or 牡蛎 or 蛤 or 蛏 or 蚌 or 罗非鱼) and (分类号=('A01K67%' or 'A23K1%') or (名称,摘要,主权项+=(养殖 or 饲养 or 栽养 or (养鱼 not 营养鱼) or 饲养 or 混养 or 谐养 or 喂养 or 暂养 or 笼养 or 驯养 or 育种 or 选育 or 培育 or 种苗 or 苗种 or 育苗 or 繁育 or 繁殖 or 饲料 or 饵料) and 分类号=('A01N%' or 'A01P%' or 'A61D19/%' or 'C12M3/%' or 'C12N5/%' or 'C12N15/%')) or 名称=(养殖 or 饲养 or 栽养 or (养鱼 not 营养鱼) or 饲养 or 谐养 or 喂养 or 混养 or 暂养 or 笼养 or 驯养 or 育种 or 选育 or 培育 or 种苗 or 苗种 or 育苗 or 繁育 or 繁殖 or 饲料 or 饵料))))
我们需要将其中的分类号呀、名称呀……等信息提取出来。看着它这一个一个的括号嵌套着,我就想着通过构造一棵树来实。
树结构
这是一棵根据需求自己构想的一棵树,root为对应的expression,child为子节点,left/rightSibRelation表示兄弟节点之间的关系
class MyTree:
def __init__(self, value, lrelation=None, rrelation=None):
self.root = value
self.child = []
self.leftSibRelation = lrelation
self.rightSibRelation = rrelation
def insert(self, child_root, lrelation=None, rrelation=None):
self.child.append(MyTree(child_root, lrelation, rrelation))
def delete(self, i):
self.child.pop(i)
def print_tree(self, symbol_num):
print('{}root:{}, leftSibRelation:{}, rightSibRelation:{}, have_child:{}'.format('--' * symbol_num + '>',
self.root,
self.leftSibRelation,
self.rightSibRelation,
self.child != []))
if self.child:
for each in self.child:
each.print_tree(symbol_num + 1)
def get_just_child(self, is_need, content_list: list):
if not self.child:
print('content:{}, flag:{}'.format(self.root, is_need))
content_list.append({
'content': self.root, 'flag': is_need})
else:
for each in self.child:
each.get_just_child(is_need, content_list)
def last_second_node(self, condition, nodes, target):
if condition in self.root:
if self.child:
child_num = 0
for each in self.child:
if condition not in each.root:
child_num += 1
if self.leftSibRelation == 'not':
target = -target
if child_num == len(self.child): # 所有儿子都没有关键字
nodes.append({
'object': self, 'target': target})
else:
for each in self.child:
if condition in each.root:
each.last_second_node(condition, nodes, target)
else:
if self.leftSibRelation == 'not':
target = -target
nodes.append({
'object': self, 'target': target})
def get_type_num(self, target, content_list):
if self.child:
for i, each in enumerate(self.child):
if each.leftSibRelation == 'not' or each.rightSibRelation == 'not':
# print(each.root)
if each.leftSibRelation