【发布时间】:2019-05-02 14:56:08
【问题描述】:
我正在尝试从带有表达式的字符串创建 JSON,但在此之前我必须替换操作数。
这是用户输入:
"Apple == 5 & (Plum == 7 | Pear == 8)"
我必须将“==”替换为“eq”,将“&”替换为“and”等(如果需要,还可以使用更多逻辑表达式)
"Apple eq 5 and (Plum eq 7 or Pear eq 8)"
最后,它应该是一个JSON结果,像这样:
{
"CategoryId": 0,
"FilterRequest":
{
"Page": 1,
"PageSize": 10,
"Filter":
{
"Logic": "and",
"Filters": [
{
"Logic": "or",
"Filters": [
{
"Field": "Plum",
"Operator": "eq",
"Value": "7"
},
{
"Field": "Pear",
"Operator": "eq",
"Value": "8"
}
]
},
{
"Field": "Apple",
"Operator": "eq",
"Value": "5"
}
]
}
}
}
你能告诉我你的想法是怎么做的吗? 谢谢
编辑:2019 年 14 月 5 日
我试图找到尽可能多的关于我的问题的信息,但我想我已经成功了。如果我选择了正确的方式。 您能给我关于以下代码的反馈或建议吗?
string = "Apple == 5 & (Plum == 7 | Pear == 8)"
string = string.replace('==', ' eq ')
string = string.replace('<>', ' ne ')
string = string.replace('>' , ' gt ')
string = string.replace('>=', ' ge ')
string = string.replace('<' , ' lt ')
string = string.replace('<=', ' le ')
string = string.replace('&' , ' and ')
string = string.replace('|' , ' or ')
string = string.replace('!=', ' not ')
print(string)
# "Apple eq 5 and (Plum eq 7 or Pear eq 8)"
import pyparsing as pp
operator = pp.Regex(r">=|<=|!=|>|<|=|eq").setName("operator")
number = pp.Regex(r"[+-]?\d+(:?\.\d*)?(:?[eE][+-]?\d+)?")
identifier = pp.Word(pp.alphas, pp.alphanums + "_")
and_ = CaselessLiteral("and").setResultsName("Logic")
or_ = CaselessLiteral("or").setResultsName("Logic")
not_ = CaselessLiteral("not").setResultsName("Logic")
logic = [
(and_, 2, (pp.opAssoc.LEFT),),
(or_, 2, pp.opAssoc.LEFT,),
(not_, 1, pp.opAssoc.RIGHT,),
]
comparison_term = (identifier | number)
condition = pp.Group(comparison_term("Field") + operator("Operator") + comparison_term("Value"))
expr = pp.operatorPrecedence(condition("Filters"), logic).setResultsName("Filter")
pars = expr.parseString(string).dump()
import json
with open("C:\\Users\\palo173\\Desktop\\example.json","w") as f:
json.dump(o,f)
实际结果,但不幸的是不是最终结果。我想听听您对下一步做什么的想法。
{
"Filter": {
"Filter": {
"Filters": [
{
"Field": "Apple",
"Operator": "eq",
"Value": "5"
},
{
"Filters": [
{
"Field": "Plum",
"Operator": "eq",
"Value": "7"
},
{
"Field": "Pear",
"Operator": "eq",
"Value": "8"
}
],
"Logic": "or"
}
],
"Logic": "and"
}
}
}
【问题讨论】:
-
到目前为止你尝试了什么?
-
shunting-yard algorithm 在解析包含括号子表达式和不同优先级的二元运算符的表达式时通常很有效。
-
谢谢@Kevin,它看起来像是我需要的东西,但不幸的是我没有在 python 中找到适合我的好例子,我可以转换成我的表单来解决我的问题。
-
Pyparsing 的返回 ParseResults 有一个
asDict方法,因此您可以直接从返回值转到字典,而无需通过已弃用的asXML到 XML 再通过 xmltodict 转换为字典。而如果使用with open(...) as f:,则不需要f.close(),with语句会自动调用文件的__exit__方法,该方法调用f.close()。这就是我们对文件使用此语句的原因。 -
@PaulMcG 谢谢。你说的对。我根据您的建议对其进行了编辑...我读到,您是 pyparsing 之父,所以也许您应该帮助我下一步做什么? ...当我想出新的东西时,我会尝试编辑代码。
标签: python json string parsing pyparsing