2014-10-29 184 views
1

如何將轉換爲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 
     } 
} 

我要尋找的辦法,而不是解決方案。如果你對這個問題進行了投票,請評論你爲什麼這麼做。

+0

是'root','key1','key3_1'等等,這種格式的標準鍵名? – aa8y 2014-10-29 06:19:44

回答

3

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

首先,讓我們用空字符串

# 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) 

然後更換的RootKey3Key3_3的出現,讓分裂所產生的串入詞和非詞

# 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 

最後,更換方括號中有波浪狀的,並且=:

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'}}" 
+0

這不是一個簡單的正則表達式問題。他想要解析的數據可能要複雜得多,並且不會包含任何預定義的鍵(名稱)。 – aa8y 2014-10-29 09:01:16

+0

@ArunAllamsetty的任務是將給定的行轉換爲json,沒有描述格式的描述。如果程序解決了這個問題 - 這可能不是海報的完整解決方案,但至少不應該得到低估。所以+1(我想給類似的解決方案,在實際發現這個之前) – pmod 2014-10-29 09:23:38

+0

@ArunAllamsetty,我不明白爲什麼這不是一個簡單的正則表達式問題。你能提供一個有效的輸入,而不是用我上面的方法轉換嗎?根據我所看到的,輸入是由令牌('=,[]')分隔的單詞序列('key1 value1'等),並且有一個以('= [')爲界的單詞的特定表達式,需要解析出來。 – 2014-10-29 12:06:43

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作爲值(如果這是有意義的)。