自定义格式为JSON

时间:2014-10-29 04:56:46

标签: python json

如何转换以下行(不知道这是什么格式)为JSON格式?

[root=Root [key1=value1, key2=value2, key3=Key3 [key3_1=value3_1, key3_2=value3_2, key3_3=Key3_3 [key3_3_1=value3_3_1]], key4=value4]]

其中RootKey3Key3_3表示复杂元素。

{
        "root": {
                "key1" : "value1",
                "key2" : "value2",
                "key3" : {
                        "key3_1" : "value3_1",
                        "key3_2" : "value3_2",
                        "key3_3" : {
                                "key3_3_1" : "value3_3_1"
                        }
                },
                "key4" : "value4
        }
}

我正在寻找方法而不是解决方案。如果您对此问题进行投票,请评论您为何这样做。

2 个答案:

答案 0 :(得分:3)

x成为具有上述序列化的字符串。

首先,让我们用空字符串替换RootKey3Key3_3的出现次数

# the string fragments like "root=Root [" need to be replaced by "root=["
# to achieve this, we match the regex pattern "\w+ ["
# This matches ALL instances in the input string where we have a word bounded by "=" & " [",
# i.e. "Root [", "Key3 [", "Key3_3" are all matched. as will any other example you can think of 
# where the `word` is composed of letters numbers or underscore followed
# by a single space character and then "["
# We replace this fragment with "[", (which we will later replace with "{")
# giving us the transformation "root=Root [" => "root=["
import re
o = re.compile(r'\w+ [[]')
y = re.sub(o, '[', x, 0)

然后,让结果字符串分成单词和非单词

# Here we split the string into two lists, one containing adjacent tokens (nonwords)
# and the other containing the words
# The idea is to split / recombine the source string with quotes around all our words

w = re.compile(r'\W+')
nw = re.compile(r'\w+')

words = w.split(y)[1:-1] # ignore the end elements which are empty.
nonwords = nw.split(y) # list elements are contiguous non-word characters, i.e not a-Z_0-9
struct = '"{}"'.join(nonwords) # format structure of final output with quotes around the word's placeholder.
almost_there = struct.format(*words) # insert words into the string

最后,将方括号替换为squigly,将=替换为:

jeeson = almost_there.replace(']', '}').replace('=', ':').replace('[', '{')
# "{'root':{'key1':'value1', 'key2':'value2', 'key3':{'key3_1':'value3_1', 'key3_2':'value3_2', 'key3_3':{'key3_3_1':'value3_3_1'}}, 'key4':'value4'}}"

答案 1 :(得分:2)

我不得不花费大约两个小时的时间,但我想我会根据您提供的格式处理所有情况。如果没有,我相信它会是一个小改变。即使你只是提出这个想法,因为无论如何我编写了它,这里是Python代码。

import json

def to_json(cust_str):
    from_index = 0
    left_indices = []
    levels = {}

    level = 0
    for i, char in enumerate(cust_str):
        if char == '[':
            level += 1
            left_indices.append(i)
            if level in levels:
                levels[level] += 1
            else:
                levels[level] = 1
        elif char == ']':
            level -= 1

    level = max(levels.keys())
    value_stack = []
    while True:
        left_index = left_indices.pop()
        right_index = cust_str.find(']', left_index) + 1
        values = {}
        pairs = cust_str[left_index:right_index][1:-1].split(',')

        if levels[level] > 0:
            for pair in pairs:
                pair = pair.split('=')
                values[pair[0].strip()] = pair[1]
        else:
            level -= 1
            for pair in pairs:
                pair = pair.split('=')
                if pair[1][-1] == ' ':
                    values[pair[0].strip()] = value_stack.pop()
                else:
                    values[pair[0].strip()] = pair[1]
        value_stack.append(values)
        levels[level] -= 1
        cust_str = cust_str[:left_index] + cust_str[right_index:]

        if levels[1] == 0:
            return json.dumps(values)

if __name__ == '__main__':
    # Data in custom format
    cust_str = '[root=Root [key1=value1, key2=value2, key3=Key3 [key3_1=value3_1, key3_2=value3_2, key3_3=Key3_3 [key3_3_1=value3_3_1]], key4=value4]]'
    # Data in JSON format
    json_str = to_json(cust_str)
    print json_str

我们的想法是,我们映射dict以自定义格式转到的级别数以及不是与这些级别对应的字符串的值的数量。与此同时,我们跟踪给定字符串中[字符的索引。然后我们从最内层dict表示开始,弹出包含[(左)索引的堆栈并解析它们。解析它们时,我们将它们从字符串中删除并继续。其余的你可以在代码中阅读。

我为你提供的数据运行它,结果如下。

{
   "root":{
      "key2":"value2",
      "key3":{
         "key3_2":"value3_2",
         "key3_3":{
            "key3_3_1":"value3_3_1"
         },
         "key3_1":"value3_1"
      },
      "key1":"value1",
      "key4":"value4"
   }    
}

为了确保它适用于更一般的情况,我使用了这个自定义字符串。

[root=Root [key1=value1, key2=Key2 [key2_1=value2_1], key3=Key3 [key3_1=value3_1, key3_2=Key3_2 [key3_2_1=value3_2_1], key3_3=Key3_3 [key3_3_1=value3_3_1]], key4=value4]]

解析了它。

{
   "root":{
      "key2":{
         "key2_1":"value2_1"
      },
      "key3":{
         "key3_2":{
            "key3_2_1":"value3_2_1"
         },
         "key3_3":{
            "key3_3_1":"value3_3_1"
         },
         "key3_1":"value3_1"
      },
      "key1":"value1",
      "key4":"value4"
   } 
}

据我所知,它应该如何解析。另外,请记住,不要去除值,因为逻辑依赖于值末尾的空格,这些值应该具有dict s作为值(如果这有意义的话)。