我有一个包含数千个 jsons 字符串的文本文档,格式为:"{...}{...}{...}"。这不是一个有效的 json,但每个 {...} 都是。
我目前使用以下正则表达式来拆分它们:
fp = open('my_file.txt', 'r')
raw_dataset = (re.sub('}{', '}\n{', fp.read())).split('\n')
这基本上打破了大括号关闭和其他打开的每一行 (}{ -> }\n{),所以我可以将它们分成不同的行。
问题是它们中很少有 tags 属性写成 "{tagName1}{tagName2}" 这打破了我的正则表达式。
一个例子是:
'{"name":\"Bob Dylan\", "tags":"{Artist}{Singer}"}{"name": "Michael Jackson"}'
被解析成
'{"name":"Bob Dylan", "tags":"{Artist}'
'{Singer}"}'
'{"name": "Michael Jackson"}'
代替
'{"name":"Bob Dylan", "tags":"{Artist}{Singer}"}'
'{"name": "Michael Jackson"}'
进一步 json 解析实现此目的的正确方法是什么?
请您参考如下方法:
使用json.JSONDecoder的raw_decode方法
>>> import json
>>> d = json.JSONDecoder()
>>> x='{"name":\"Bob Dylan\", "tags":"{Artist}{Singer}"}{"name": "Michael Jackson"}'
>>> d.raw_decode(x)
({'tags': '{Artist}{Singer}', 'name': 'Bob Dylan'}, 47)
>>> x=x[47:]
>>> d.raw_decode(x)
({'name': 'Michael Jackson'}, 27)
raw_decode 返回一个二元组,第一个元素是解码后的 JSON,第二个元素是 JSON 结束后下一个字节在字符串中的偏移量。
循环直到结束或遇到无效的 JSON 元素:
>>> while True:
... try:
... j,n = d.raw_decode(x)
... except ValueError:
... break
... print(j)
... x=x[n:]
...
{'name': 'Bob Dylan', 'tags': '{Artist}{Singer}'}
{'name': 'Michael Jackson'}
当循环中断时,检查 x 将显示它是否处理了整个字符串或是否遇到了 JSON 语法错误。
对于一个非常长的短元素文件,您可以将一个 block 读入缓冲区并应用上述循环,在循环中断后将剩余的任何内容与下一个 block 连接起来。
