问题描述
"(a=1) and ((b=2) or (c=3))"
哪里有“和” ,我需要在python中将其转换为此,
"query[(a=1)].add(query[(b=2) or (c=3)])"
您可以看到发生了两件事,
每当我做 add 时,我都会用query []包装操作数,然后将a and b
转换为a.add(b)
。
如果字符串是类似的另一个示例,
"(a=1) and ((b=2) and (c=3))"
,其中有两个和。
结果应该是
"query[(a=1)].add(query[(b=2)].add(query[(c=3)]))"
我不能对此进行硬编码,因为括号可以是任何嵌套级别。
我上面显示的表达式是简化的解释,也可能是这样,
'((Attributes.name=="usertype") & (cast(User_Values.value,db.String())=='"Employee"')) and (((Attributes.name=="emails") & (User_Values.value.contains([{"type":"examplecom"}]))) or ((Attributes.name=="emails") & (User_Values.value.contains([{"value":"exampleorg"}]))))'
进步:-
ms = '((Attributes.name=="usertype") & (cast(User_Values.value,db.String())=='"Employee"')) and (((Attributes.name=="emails") & (User_Values.value.contains([{"type":"examplecom"}]))) and ((Attributes.name=="emails") & (User_Values.value.contains([{"value":"exampleorg"}]))))'
scanner = originalTextFor(nestedExpr('(',')'))
for match in scanner.searchString(ms):
print("match is ..........",match[0])
明白了
((Attributes.name=="usertype") & (cast(User_Values.value,db.String())==Employee))
(((Attributes.name=="emails") & (User_Values.value.contains([{"type":"examplecom"}]))) and ((Attributes.name=="emails") & (User_Values.value.contains([{"value":"exampleorg"}]))))
接下来,我正在寻找和操作数的最外括号内容。 在上面的示例中没有发生这种情况。它仅给出两个独立的括号内容。
于2020年10月8日编辑
Ken T的解决方案很有意义,但是我注意到那里存在一个问题。
"((b=2) and (c=3)) and (a=1)"
,其中有两个和。
结果应该是
"query[(b=2)].add(query[(c=3)]).add(query[(a=1)])"
但结果是,
query[((b=2)].add(query[c=3)) and (a=1])
示例
输入
'(((Values.attribute=="1") & (cast(Values.value,db.String()).like('"%a%"'))) and ((Values.attribute=="3") & (cast(Values.value,db.String()).like('"%b%"')))) and ((Values.attribute=="1") & (cast(Values.value,db.String()).like('"%a%"')))'
预期输出为
query[((Values.attribute=="1") & (cast(Values.value,db.String()).like(%a%)))]
.add(query[(Values.attribute=="3") & (cast(Values.value,db.String()).like(%b%))])
.add(query[(Values.attribute=="1") & (cast(Values.value,db.String()).like(%a%)]))
但实际输出是
query[(((Values.attribute=="1") & (cast(Values.value,db.String()).like(%b%))))]
.add(query[(Values.attribute=="1") & (cast(Values.value,db.String()).like(%a%)]))
遵守括号。
不得在query []
中包含和.add()我该如何纠正Ken T的解决方案。
解决方法
递归!这是一个递归问题。
import re
def queryGen(text,lastOP=''):
pattern = re.compile("\((.+?)\)\s+(and|or)+\s\((.+)\)")
res = pattern.search(text)
if not res:
if lastOP == 'or':
return text
elif lastOP == 'and':
return f'query[{text}]'
if res.group(2)=='and':
return f"query[({res.group(1)})].add({queryGen(res.group(3),lastOP='and')})"
if res.group(2)=='or':
return f"query[({res.group(1)}) or ({queryGen(res.group(3),lastOP='or')})]"
print(queryGen("(a=1) and ((b=2) or (c=3))"))
print(queryGen("(a=1) and ((b=2) and (c=3))"))
print(queryGen("""((Attributes.name=="usertype") & (cast(User_Values.value,db.String())=='"Employee"')) and (((Attributes.name=="emails") & (User_Values.value.contains([{"type":"examplecom"}]))) or ((Attributes.name=="emails") & (User_Values.value.contains([{"value":"exampleorg"}]))))"""))
返回:
query[(a=1)].add(query[(b=2) or (c=3)])
query[(a=1)].add(query[(b=2)].add(query[c=3]))
query[((Attributes.name=="usertype") & (cast(User_Values.value,db.String())=='"Employee"'))].add(query[((Attributes.name=="emails") & (User_Values.value.contains([{"type":"examplecom"}]))) or ((Attributes.name=="emails") & (User_Values.value.contains([{"value":"exampleorg"}])))])
您可以在以下网站上交互式测试正则表达式模式: