使用Python将JavaScript数组破解为JSON

时间:2009-07-17 16:34:59

标签: javascript python json

我从远程站点获取一个.js文件,该文件包含我想要使用我的Google App Engine站点上的simplejson库处理为JSON的数据。 .js文件如下所示:

var txns = [
    { apples: '100', oranges: '20', type: 'SELL'}, 
    { apples: '200', oranges: '10', type: 'BUY'}]

我无法控制此文件的格式。我最初只是为了破解它而做的是将"var txns = "位从字符串中删除,然后在字符串上执行一系列.replace(old, new, [count]),直到它看起来像标准JSON:

cleanJSON = malformedJSON.replace("'", '"').replace('apples:', '"apples":').replace('oranges:', '"oranges":').replace('type:', '"type":').replace('{', '{"transaction":{').replace('}', '}}')

现在它看起来像:

[{ "transaction" : { "apples": "100", "oranges": "20", "type": "SELL"} }, 
 { "transaction" : { "apples": "200", "oranges": "10", "type": "BUY"} }]

您如何解决此格式问题?是否有一种已知的方法(库,脚本)将JavaScript数组格式化为JSON表示法?

4 个答案:

答案 0 :(得分:5)

使用PyParsing编写自己的小方块并不太难。

import json
from pyparsing import *

data = """var txns = [
   { apples: '100', oranges: '20', type: 'SELL'}, 
   { apples: '200', oranges: '10', type: 'BUY'}]"""


def js_grammar():
    key = Word(alphas).setResultsName("key")
    value = QuotedString("'").setResultsName("value")
    pair = Group(key + Literal(":").suppress() + value)
    object_ = nestedExpr("{", "}", delimitedList(pair, ","))
    array = nestedExpr("[", "]", delimitedList(object_, ","))
    return array + StringEnd()

JS_GRAMMAR = js_grammar()

def parse(js):
    return JS_GRAMMAR.parseString(js[len("var txns = "):])[0]

def to_dict(object_):
    return dict((p.key, p.value) for p in object_)

result = [
    {"transaction": to_dict(object_)}
    for object_ in parse(data)]
print json.dumps(result)

这将打印

[{"transaction": {"type": "SELL", "apples": "100", "oranges": "20"}},
 {"transaction": {"type": "BUY", "apples": "200", "oranges": "10"}}]

您还可以将分配添加到语法本身。鉴于已经有现成的解析器,你应该更好地使用它们。

答案 1 :(得分:4)

我会在大多数情况下使用yaml解析器。它带有GAE以及它用于配置文件。 Json是yaml的子集。

你所要做的就是摆脱“var txns =”然后yaml应该做其余的事情。

import yaml

string = """[{ apples: '100', oranges: '20', type: 'SELL'}, 
             { apples: '200', oranges: '10', type: 'BUY'}]"""

list = yaml.load(string)

print list

这会给你。

[{'type': 'SELL', 'apples': '100', 'oranges': '20'},
 {'type': 'BUY', 'apples': '200', 'oranges': '10'}]

加载后,您可以随时将其作为json转储回来。

答案 2 :(得分:0)

如果你知道这就是它总是会是什么样子,你可以做一个正则表达式来找到以空格分隔的文本,以冒号结尾并用引号括起来。

我总是担心像这样的正则表达式的意外输入。你怎么知道远程源不会改变你得到的东西?

答案 3 :(得分:0)

您可以创建一个包含Javascript脚本的中间页面,该脚本只加载远程脚本并将其转储到JSON。然后Python可以向您的中间页面发出请求并获得漂亮的JSON。