Python递归函数或循环将字符串转换为json逻辑对象

尼利修斯

我有这个功能:

def req_splitter(req_string):
    req = {}
    if " AND " in req_string:
        cond = "AND"
        req_splitted = req_string.split(" AND ")
    elif " OR " in req_string:
        cond = "OR"
        req_splitted = req_string.split(" OR ")
    else:
        cond = "AND"
        req_splitted = [req_string]

    if len(req_splitted) > 1:
        for sub_req in req_splitted:
            sub_req_splitted = req_splitter(sub_req)
            req[cond] = list()#new_req
            req[cond].append(sub_req_splitted)
    else:
        req[cond] = req_splitted
    return req

它旨在将类似于以下的字符串转换为json-logic条件:

Barracks AND Tech Lab
Lair OR Hive
Hatchery OR Lair OR Hive
Cybernetics Core AND Gateway OR Warpgate
Forge AND Twilight Council AND Ground Armor 1
Spire OR Greater Spire AND Hive AND Flyer Flyer Carapace 2
Spire OR Greater Spire AND Lair OR Hive AND Flyer Attacks 1

json_logic条件如下所示:

{
    "and": [
            {
            "or": [
                "Gateway",
                "Warpgate"
            ]
        },
        "Cybernetics Core"
    ]
}

我的递归函数应该如何工作,以帮助我像上面的示例一样将字符串拆分为条件对象?


为了帮助您了解问题,请执行以下操作:

json_logic是一个检查条件的模块,就像您在上面看到的字典一样,并根据比较的内容返回一些结果。

以及条件的工作方式:键值par是一个逻辑语句。该键代表逻辑条件。列表中的值代表操作数。如果值本身不是列表而是字典,则它将递归。

您可以将其与“波兰语表示法进行比较

最后一件事-AND语句比OR语句具有更高的优先级,并且OR语句始终在一起。

马丁·彼得斯(Martijn Pieters)

您需要编写一个简单的自上而下的解析器。无与伦比的effbot就这种事情写了一篇很棒的教程

符号化是刚刚拆分r'\s+(OR|AND)\s+'正则表达式,然后认识ORAND作为经营者,其余为文字。ANDOR标记.led()方法可以拉平同类型的直接嵌套运营商。

我使用更多的OOP(而不是全局变量)实现了此处描述的内容,并使它与Python 2和3兼容:

import re
from functools import partial


class OpAndToken(object):
    lbp = 10
    op = 'and'
    def led(self, parser, left):
        right = parser.expression(self.lbp)
        operands = []
        for operand in left, right:
            # flatten out nested operands of the same type
            if isinstance(operand, dict) and self.op in operand:
                operands.extend(operand[self.op])
            else:
                operands.append(operand)
        return {self.op: operands}


class OpOrToken(OpAndToken):
    lbp = 20
    op = 'or'


class LiteralToken(object):
    def __init__(self, value):
        self.value = value
    def nud(self):
        return self.value


class EndToken(object):
    lbp = 0


class Parser(object):
    operators = {'AND': OpAndToken, 'OR': OpOrToken}
    token_pat = re.compile("\s+(AND|OR)\s+")

    def __init__(self, program):
        self.program = program
        self.tokens = self.tokenizer()
        self.token = next(self.tokens)

    def expression(self, rbp=0):
        t = self.token
        self.token = next(self.tokens)
        left = t.nud()
        while rbp < self.token.lbp:
            t = self.token
            self.token = next(self.tokens)
            left = t.led(self, left)
        return left

    def tokenizer(self):
        for tok in self.token_pat.split(self.program):
            if tok in self.operators:
                yield self.operators[tok]()
            else:
                yield LiteralToken(tok)
        yield EndToken()

    def parse(self):
        return self.expression()

这会将您的格式解析为预期的输出:

>>> Parser('foo AND bar OR spam AND eggs').parse()
{'and': ['foo', {'or': ['bar', 'spam']}, 'eggs']}

输入行上的演示:

>>> from pprint import pprint
>>> tests = '''\
... Barracks AND Tech Lab
... Lair OR Hive
... Hatchery OR Lair OR Hive
... Cybernetics Core AND Gateway OR Warpgate
... Forge AND Twilight Council AND Ground Armor 1
... Spire OR Greater Spire AND Hive AND Flyer Flyer Carapace 2
... Spire OR Greater Spire AND Lair OR Hive AND Flyer Attacks 1
... '''.splitlines()
>>> for test in tests:
...     pprint(Parser(test).parse())
...
{'and': ['Barracks', 'Tech Lab']}
{'or': ['Lair', 'Hive']}
{'or': ['Hatchery', 'Lair', 'Hive']}
{'and': ['Cybernetics Core', {'or': ['Gateway', 'Warpgate']}]}
{'and': ['Forge', 'Twilight Council', 'Ground Armor 1']}
{'and': [{'or': ['Spire', 'Greater Spire']}, 'Hive', 'Flyer Flyer Carapace 2']}
{'and': [{'or': ['Spire', 'Greater Spire']},
         {'or': ['Lair', 'Hive']},
         'Flyer Attacks 1']}

请注意,对于连续的多个ORAND运算符,将操作数组合在一起。

我将留给(...)读者添加括号的支持本教程向您展示如何做到这一点(只需将advance()函数作为Parser的方法,并将解析器也传递给.nud()调用,或者在创建令牌类实例时传递解析器)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

python将字符串转换为逻辑门函数

来自分类Dev

将Python对象转换为JSON字符串

来自分类Dev

如何将浏览器返回的json对象转换为python lambda函数中的字符串

来自分类Dev

python:将for循环转换为递归函数

来自分类Dev

python:将for循环转换为递归函数

来自分类Dev

javascript将JSON字符串转换为JSON对象

来自分类Dev

无法将 json 字符串转换为 json 对象

来自分类Dev

Spring - 将 JSON 字符串转换为 JSON 对象

来自分类Dev

将字节从for循环转换为python中的字符串

来自分类Dev

将点分隔的字符串转换为JSON对象

来自分类Dev

将JSON对象数组转换为字符串

来自分类Dev

将打字稿对象转换为json字符串

来自分类Dev

ExpressJS / AngularJS:将JSON对象转换为字符串

来自分类Dev

将字符串转换为Javascript中的JSON对象

来自分类Dev

将HTML字符串转换为JSON对象

来自分类Dev

无法将JSON字符串转换为对象?

来自分类Dev

将jira json字符串转换为java对象

来自分类Dev

将JSON字符串转换为对象Javascript

来自分类Dev

将字符串转换为JSON对象C#

来自分类Dev

将字符串转换为Javascript中的JSON对象

来自分类Dev

无法将空字符串转换为JSON对象

来自分类Dev

ExpressJS / AngularJS:将JSON对象转换为字符串

来自分类Dev

使用Java将字符串转换为JSON对象

来自分类Dev

将JSON字符串转换为对象

来自分类Dev

将字符串转换为JSON对象

来自分类Dev

将 JSON 字符串转换为 JS 对象

来自分类Dev

将解密后的字符串转换为 JSON 对象

来自分类Dev

将JSON字符串转换为Angular函数?

来自分类Dev

将JSON字符串转换为函数参数