2016-02-23 42 views
1

如何解析嵌入Javascript常量或變量的JSON字符串?Python:解析帶有嵌入式Javascript常量/變量的JSON字符串

例如,如何解析一個像這樣的JSON字符串?

{ 
    "menu": { 
     "id": "file", 
     "value": "File", 
     "popup": { 
     "menuitem": [ 
      { 
      "value": "New", 
      "onclick": Handlers.NEW 
      }, 
      { 
      "value": "Open", 
      "onclick": Handlers.OPEN 
      }, 
      { 
      "value": "Custom", 
      "onclick": "function(){doSomething(Handlers.OPEN);}" 

      } 
     ] 
     } 
    } 
    } 

所有的驗證器當然都認爲JSON是無效的,但當在定義相應Javascript對象的上下文中進行評估時,它是完全有效的。

首先想到的是在將字符串提供給JSON解析器之前對其進行預處理,但這很棘手,因爲現有字符串內可能會出現相同的字符串(如示例JSON中所示),並且這將需要一些正則表達式來擺弄,以便可靠地檢測是否例如Handlers.NEW用作未修飾的值,或在現有的字符串值中。

有沒有一種乾淨的方式來處理這個用例,而不必手動正則表達式替換?

+1

事實上,它是不是有效的JSON(儘管這是一個有效的JavaScript對象)。您可能需要爲此編寫自己的解析器。 – L3viathan

回答

1
​​

這將字符串解析爲抽象語法樹,然後遞歸地構建一個Python對象,將屬性轉換爲字符串。

+0

這很美! – ccpizza

+0

@ccpizza謝謝!如果你發現一個案件中斷,讓我知道。唯一不可修復的情況是一個對象不是語法上有效的Python。 – L3viathan

+0

的作品像一個魅力與一個相當複雜的JSON幾乎1MB的大小。非常感謝! – ccpizza

2

可以使用AST模塊:

import ast 

data = """{ 
    "menu": { 
     "id": "file", 
     "value": "File", 
     "popup": { 
     "menuitem": [ 
      { 
      "value": "New", 
      "onclick": Handlers.NEW 
      }, 
      { 
      "value": "Open", 
      "onclick": Handlers.OPEN 
      }, 
      { 
      "value": "Custom", 
      "onclick": "function(){doSomething(Handlers.OPEN);}" 

      } 
     ] 
     } 
    } 
    }""" 

def transform(item): 
    if isinstance(item, ast.Dict): 
     return dict(zip(map(transform,item.keys), map(transform, item.values))) 
    elif isinstance(item, ast.List): 
     return map(transform, item.elts) 
    elif isinstance(item, ast.Str): 
     return item.s 
    else: 
     return item 

print transform(ast.parse(data).body[0].value)