我有一个JSON对象流,就像通过TCP或WebSockets上的JSON-RPC一样.没有长度前缀或分隔符,因为JSON是自我分隔的.所以,当我从流中读取时,我可能会得到这样的结果:
{"id":1,"result":{"answer":23},"error":null}
{"id":2,"result":{"answer":42},"error":null}
{"id":3,"result":{"answ
Run Code Online (Sandbox Code Playgroud)
我需要逐个解析每个JSON对象.我不能用JSON.parse做到这一点,因为它只会在最后为无关数据抛出语法错误.
当然,通过这个例子,我可以逐行进行,但我不能依赖看起来那样的空白; JSON-RPC可以像这样容易:
{
"id": 1,
"result": {
"answer": 23
},
"error":null
}
Run Code Online (Sandbox Code Playgroud)
或这个:
{"id":1,"result":{"answer":23},"error":null}{"id":2,"result":{"answer":42},"error":null}
Run Code Online (Sandbox Code Playgroud)
对于其他语言的大多数解析器,显而易见的答案是这样的(使用Python作为示例):
buf = ''
decoder = json.JSONDecoder()
def onReadReady(sock):
buf += sock.read()
obj, index = decoder.raw_decode(buf)
buf = buf[index:]
if obj:
dispatch(obj)
Run Code Online (Sandbox Code Playgroud)
但我在JS中找不到类似的东西.我查看了我能找到的每个JS解析器,它们都有效地等同于JSON.parse.
我尝试查看各种JSON-RPC框架,看看他们如何处理这个问题,而他们却没有.他们中的许多人都认为recv总是会返回一个send(这对于JSON-RPC通过HTTP工作正常,但不适用于TCP或WebSockets - 当然,它可能在本地测试中起作用).其他人实际上并没有处理JSON-RPC,因为他们在空白上添加了需求(其中一些甚至对JSON-RPC都不起作用).
我可以编写一个分隔括号和引号的分隔符检查(当然是处理转义和引用),或者只是从头开始编写JSON解析器(或者从另一种语言编写端口1,或者修改http://code.google.com/p/json-sans-eval /),但我不敢相信之前没有人这样做过.
编辑:我已经做了两个版本的自己,http://pastebin.com/fqjKYiLw基于JSON的SAN-EVAL和http://pastebin.com/8H4QT82b基于Crockford的参考递归下降解析器json_parse.js.我仍然宁愿使用经过其他人测试和使用的东西,而不是自己编写代码,所以我将这个问题保持开放.
aba*_*ert 15
经过一个月的搜索替代品而没有找到任何有用的东西,我决定编写一堆不同的实现并测试它们,然后我修改了Crockford的参考递归下降解析器(如问题所述,可在此处获得)).
它不是最快的,但在我做的每一次测试中它都足够快.更重要的是,它可以捕获明显错误的JSON,当它与不完整的JSON不一致时,比大多数其他替代方案要好得多.最重要的是,它需要从众所周知且经过验证的代码库中进行非常简单的更改,这使我对其正确性更有信心.
尽管如此,如果有人知道一个比我更好的图书馆(并且只是被许多项目使用而不仅仅是我认为是一个重要的资格),我很想知道它.