input: ( A or B ) and C or ( ( i and h ) or ( e or f ) ) and ( o and p )
output:
{
'operator': 'and', 'condition': [{
'operator': 'and',
'condition': [{'operator': 'or', 'condition': ['A', 'B']}, {
'operator': 'or',
'condition': ['C', {
'operator': 'or',
'condition': [{'operator': 'and', 'condition': ['i', 'h']}, {'operator': 'or', 'condition': ['e', 'f']}]
}]
}]
}, {'operator': 'and', 'condition': ['o', 'p']}]
}
----------------------------------
__author__ = 'Administrator'
import bisect
# op = or / and ,
def doOp(op, opIndexArray, iarray):
for index in opIndexArray:
lfindindex = index -1
lvalue = iarray[lfindindex]
while lvalue is None and lfindindex > 0:
lfindindex -=1
lvalue = iarray[lfindindex]
rfindindex = index + 1
rvalue = iarray[rfindindex]
while rvalue is None and rfindindex < len(iarray)-1:
rfindindex +=1
rvalue = iarray[rfindindex]
if lvalue is None or rvalue is None :
print("data is error, stop !")
return
##处理过的用None进行复位
iarray[lfindindex] = None
iarray[rfindindex] = None
## result
iarray[index] = {
"operator": op,
"condition":[lvalue, rvalue]
}
# 处理没有括号得表达式,比如:a and c and d or c and J or D
def doNoBreakLogic(iarray):
print("处理没有括号得表达式:", iarray)
opOrIndexArray = [i for i, v in enumerate(iarray) if v == 'or']
opAndIndexArray = [i for i, v in enumerate(iarray) if v == 'and']
print("opOrIndexArray:", opOrIndexArray, "opAndIndexArray:", opAndIndexArray)
doOp('or', opOrIndexArray, iarray)
print(iarray)
doOp('and', opAndIndexArray, iarray)
iresult = [v for v in iarray if v is not None]
if len(iresult) ==1:
return iresult[0]
else:
return None
bds = '( A or B ) and C or ( ( i and h ) or ( e or f ) )'
bdsArr = bds.split(' ')
print("original:",bdsArr,len(bdsArr))
result = []
lbreak = [i for i,v in enumerate(bdsArr) if v == '(']
rbreak = [i for i,v in enumerate(bdsArr) if v == ')']
print(lbreak, rbreak)
#lbi is ( index of bdsArray; rbi is ) index of bdsArray .
lbreak.reverse()
print(lbreak, rbreak)
# 找处"( " 对应得" )" index 存放于 lbreak, rrbreak
rrbreak = []
for lbi in lbreak:
rbi = bisect.bisect(rbreak, lbi) #按顺序插入,只返回插入得下标,不插入数组。
rbi_v = rbreak[rbi]
if rbi_v:
rrbreak.append(rbi_v)
rbreak.pop(rbi)
else:
print("未匹配到右括号")
print(lbreak, rrbreak)
# 先将 表达式中括号去掉, 在 进行 OR AND 运算
for i,lv in enumerate(lbreak):
rv = rrbreak[i]
# 取两个括号之间的表达式
print(lv,rv)
ss = bdsArr[lv+1:rv]
print("ss:",ss)
doResult = doNoBreakLogic(ss)
if doResult is None:
print("doNoBreakLogic is error!")
break
print("doNoBreakLogic:", doResult)
print("bdsArr---:", bdsArr, len(bdsArr))
bdsArr[lv:rv+1]=[None for i in range(rv-lv+1)]
print("bdsArr***:", bdsArr, len(bdsArr))
bdsArr[lv] = doResult
print("bdsArr+++:", bdsArr, len(bdsArr))
# bdsArr为去掉括号后的表达式,接下来在进行OR,AND运算
result = doNoBreakLogic(bdsArr)
print("result::", result)
---------------------------------------------------------------------------------------------------------
( A or B ) and C or ( ( i and h ) or ( e or f ) ) 转化为Es查询表达式。
最新推荐文章于 2022-12-05 16:55:47 发布