2012-08-30 82 views
8

的一個級別,我有以下字符串:解析只JSON

'{ 
    "key1": "val1", 
    "key2": ["a","b", 3], 
    "key3": {"foo": 27, "bar": [1, 2, 3]} 
}' 

我想分析只能在水平,使結果應該是一個級別字典,鍵和值應該只是一個字符串(不要」噸需要解析它)

對於給定的字符串,它應該給我以下字典:

{ 
    "key1": "val1", 
    "key2": "['a','b', 3]", 
    "key3": "{'foo': 27, 'bar': [1, 2, 3]}" 
} 

有一個快速的方法來做到這一點?不需要將整個字符串解析爲json並將所有值轉換回字符串。

+0

你已經解析了整個JSON字符串,並抓住了部分字符串..這是可行的,但我懷疑它是值得的。表現真的很關鍵嗎? –

+0

是的,它應該是性能關鍵代碼的一部分 –

+0

另外,如果我直接將每個值轉換爲str,我將收到令人討厭的u字符串前綴: 'foo = json.loads('{「key1」:「val1」,「key2」 :[「a」,「b」,3],「key3」:{「foo」:27,「bar」:[1,2,3]}''' ' v))for k,v in foo.iteritems()])' will give me: '{u'key1':'val1', u'key2':「[u'a',u'b' ,3]「, u'key3':」{u'foo':27,u'bar':[1,2,3]}「' –

回答

3

幾乎沒有一個答案,但我只看到兩種可能性:

  1. 加載完整JSON和轉儲回值,你已經在你的問題
  2. 排除在包裝中的值修改內容報價,從而使JSON負載率串值

說實話,我覺得這是爲「性能的關鍵 JSON解析代碼」沒有這樣的事,它只是聽起來錯了,所以我同去第一opti上。

1

我不知道現在如果它真的你所需要的,但儘量

>>> import json 
>>> val = """ 
... { 
... "key1": "val1", 
... "key2": ["a","b", 3], 
... "key3": {"foo": 27, "bar": [1, 2, 3]} 
... } 
... """ 
>>> dict((k,json.dumps(v)) for k,v in json.loads(val).items()) 
{u'key3': '{"foo": 27, "bar": [1, 2, 3]}', u'key2': '["a", "b", 3]', u'key1': '"val1"'} 

這是有點棘手,因爲你負荷JSON完整的對象並不僅僅是傾倒回值字典。

+1

」不將整個字符串解析爲json並將所有值轉換回字符串。「 –

1

我想你可以解決這個使用正則表達式,它爲我工作:

import re 
pattern = re.compile('"([a-zA-Z0-9]+)"\s*:\s*(".*"|\[.*\]|\{.*\})')  
dict(re.findall(pattern, json_string)) 

但我不知道這是更快,你需要嘗試使用您的數據。

[編輯]

是的,它更快。我嘗試了下面的腳本,正則表達式版本快了5倍。使用

JSON模塊:

import json 

val=''' 
{ 
    "key1": "val1", 
    "key2": ["a","b", 3], 
    "key3": {"foo": 27, "bar": [1, 2, 3]} 
} 
''' 

for n in range(100000): 
    dict((k,json.dumps(v)) for k,v in json.loads(val).items()) 

使用正則表達式:

import re 

val='''{ 
    "key1": "val1", 
    "key2": ["a","b", 3], 
    "key3": {"foo": 27, "bar": [1, 2, 3]} 
}''' 

pattern = re.compile('"([a-zA-Z0-9]+)"\s*:\s*(".*"|\[.*\]|\{.*\})')  
for n in range(100000): 
    dict(re.findall(pattern, val))