1 Вопрос: Python - создать JSON из строки с выражением распознавания

вопрос создан в Thu, May 2, 2019 12:00 AM

Я пытаюсь создать JSON из строки с выражением, но перед этим мне нужно заменить операнд.

Это входные данные от пользователя:

"Apple == 5 & (Plum == 7 | Pear == 8)"

Я должен заменить "==" на "eq" или "&" на «и» и т. д. (и более логичное выражение, если это необходимо)

"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"
                                       }
                                   ]
                               }

                }
}

Не могли бы вы рассказать мне свои идеи, как это сделать? может быть, единственный способ ... спасибо

РЕДАКТИРОВАНИЕ: 14/5/2019

Я пытался найти как можно больше информации о своей проблеме, и я думаю, что на полпути. Если я когда-либо выбрал правильный путь. Не могли бы вы дать мне отзыв или совет по поводу кода ниже?

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"
        }
    }
}
    
- 3
  1. Что вы уже пробовали?
    2019-05-02 14: 57: 35Z
  2. алгоритм шунтирующего двора обычно эффективен при разборе выражений, которые содержат вложенные выражения в скобках и двоичные операторы различного приоритета.
    2019-05-02 14: 59: 01Z
  3. Спасибо @Kevin, это выглядит как-то, что мне нужно, но, к сожалению, я не нашел хорошего примера в python для меня, что я мог бы преобразовать в свою форму, чтобы решить моя проблема.
    2019-05-06 11: 48: 42Z
  4. Возвращенный Pyparsing метод ParseResults имеет метод asDict, так что вы можете напрямую перейти от возвращенного значения к dict, не проходя через устаревший asXML в XML, а затем xmltodict для преобразования в диктат И если вы используете with open(...) as f:, то нет необходимости в f.close(), оператор with автоматически вызовет метод файла __exit__, который вызывает f.close(). Вот почему мы используем этот оператор для файлов>.
    2019-05-11 00: 51: 15Z
  5. @ PaulMcG Спасибо. Вы правы. Я отредактировал его по вашей рекомендации ... Я прочитал, что вы отец pyparsing, так что, может быть, вы должны помочь мне, что дальше? ... Я пытаюсь отредактировать код, когда я придумываю что-то новое.
    2019-05-14 13: 22: 08Z
  6. 1 ответ                              1                         

    Я бы предложил использовать

    string.replace(old, new, count)
    # count is optional, leave it blank like below and it does all occurences
    

    например

    string = "Apple == 5 & (Plum == 7 | Pear == 8)"
    
    string.replace('==', 'eq')
    string.replace('&', 'and')
    string.replace('|', 'or')
    
    print(string)
    
    >Apple eq 5 and (Plum eq 7 or Pear eq 8
    # and so on
    

    Теперь это делает только замену, может быть, использовать цикл for для перехода к списку строк, но я думаю, вы можете это сделать.

        
    0
    2019-05-02 15: 09: 46Z
источник размещен Вот