从文本文件检索JSON对象(使用Python)
我有数千个包含多个JSON对象的文本文件,但不幸的是,这些对象之间没有分隔符。对象存储为字典,其中一些字段本身就是对象。每个对象可能具有数量可变的嵌套对象。具体而言,对象可能如下所示:从文本文件检索JSON对象(使用Python),python,json,object,Python,Json,Object,我有数千个包含多个JSON对象的文本文件,但不幸的是,这些对象之间没有分隔符。对象存储为字典,其中一些字段本身就是对象。每个对象可能具有数量可变的嵌套对象。具体而言,对象可能如下所示: {field1: {}, field2: "some value", field3: {}, ...} import re import json jsonstr = open('test.json').read() p = re.compile( '}\s*{' ) jsonstr = p.sub( '
{field1: {}, field2: "some value", field3: {}, ...}
import re
import json
jsonstr = open('test.json').read()
p = re.compile( '}\s*{' )
jsonstr = p.sub( '}\n{', jsonstr )
jsonarr = jsonstr.split( '\n' )
for jsonstr in jsonarr:
jsonobj = json.loads( jsonstr )
print json.dumps( jsonobj )
数百个这样的对象在文本文件中没有分隔符而被连接在一起。这意味着我既不能使用json.load()
也不能使用json.load()
关于我如何解决这个问题的任何建议。是否有已知的解析器可以执行此操作?假设您在文件中文本的开头添加了一个[并使用了一个版本的json.load(),当它检测到查找{而不是预期的逗号(或到达文件的结尾)时,会吐出刚刚完成的对象?假设您添加了一个[到文件中文本的开头,并使用json.load()的一个版本,当它检测到查找{而不是预期的逗号(或到达文件的末尾)的错误时,会吐出刚刚完成的对象?为什么不将文件作为字符串加载,将所有}{替换为},{并用[]环绕整个对象?类似于:
re.sub('\}\s*?\{', '\}, \{', string_read_from_a_file)
或者简单的字符串替换,如果您确定在}{之间总是没有空格的话
如果您希望}{也出现在字符串中,您也可以在}{上拆分,并使用json.load对每个片段进行求值,如果出现错误,该片段不完整,您必须将下一个片段添加到第一个片段中,以此类推。为什么不将文件作为字符串加载,将所有}{替换为},{并用[]?类似于:
re.sub('\}\s*?\{', '\}, \{', string_read_from_a_file)
或者简单的字符串替换,如果您确定在}{之间总是没有空格的话
如果您希望}{也出现在字符串中,您也可以在}{上拆分,并使用json.load计算每个片段,如果出现错误,该片段不完整,您必须将下一个片段添加到第一个片段中,以此类推。每次读取一个计数器时,读取该文件如何{被找到,当你遇到一个}时,它将递减。当你的计数器达到0时,你将知道你已经到达了第一个对象的末尾,所以通过json.load发送它并再次开始计数。然后重复一次直到完成。如何通过文件读取,每次一个计数器递增一次{被找到,当你遇到一个}时,它将递减。当你的计数器达到0时,你将知道你已经到达了第一个对象的末尾,所以通过json.load发送它并再次开始计数。然后重复直到完成。 据我所知,
}{
没有出现在有效的JSON中,因此,当尝试获取连接的单独对象的字符串时,以下内容应该是完全安全的(txt
是您文件的内容)。它不需要任何导入(即使是re
模块)来完成此操作:
retrieved_strings = map(lambda x: '{'+x+'}', txt.strip('{}').split('}{'))
或者,如果您喜欢列表理解(如David Zwicker在评论中提到的),您可以这样使用它:
retrieved_strings = ['{'+x+'}' for x in txt.strip('{}').split('}{'))]
它将导致retrieved_strings
成为一个字符串列表,每个字符串包含单独的JSON对象。请参见此处的证明:
例子
以下字符串:
'{field1:"a",field2:"b"}{field1:"c",field2:"d"}{field1:"e",field2:"f"}'
将变成:
['{field1:"a",field2:"b"}', '{field1:"c",field2:"d"}', '{field1:"e",field2:"f"}']
如。解决方案中所述
据我所知,}{
没有出现在有效的JSON中,因此,当尝试获取连接的单独对象的字符串时,以下内容应该是完全安全的(txt
是您文件的内容)。它不需要任何导入(即使是re
模块)来完成此操作:
retrieved_strings = map(lambda x: '{'+x+'}', txt.strip('{}').split('}{'))
或者,如果您喜欢列表理解(如David Zwicker在评论中提到的),您可以这样使用它:
retrieved_strings = ['{'+x+'}' for x in txt.strip('{}').split('}{'))]
它将导致retrieved_strings
成为一个字符串列表,每个字符串包含单独的JSON对象。请参见此处的证明:
例子
以下字符串:
'{field1:"a",field2:"b"}{field1:"c",field2:"d"}{field1:"e",field2:"f"}'
将变成:
['{field1:"a",field2:"b"}', '{field1:"c",field2:"d"}', '{field1:"e",field2:"f"}']
如中所述。这将从字符串中解码JSON对象的“列表”:
from json import JSONDecoder
def loads_invalid_obj_list(s):
decoder = JSONDecoder()
s_len = len(s)
objs = []
end = 0
while end != s_len:
obj, end = decoder.raw_decode(s, idx=end)
objs.append(obj)
return objs
这里的好处是,您可以很好地使用解析器,因此它会不断准确地告诉您在哪里发现了错误
示例
>>> loads_invalid_obj_list('{}{}')
[{}, {}]
>>> loads_invalid_obj_list('{}{\n}{')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "decode.py", line 9, in loads_invalid_obj_list
obj, end = decoder.raw_decode(s, idx=end)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 376, in raw_decode
obj, end = self.scan_once(s, idx)
ValueError: Expecting object: line 2 column 2 (char 5)
>>> print json.loads('{}', cls=ConcatJSONDecoder)
[{}]
>>> print json.load(open('file'), cls=ConcatJSONDecoder)
[{}]
>>> print json.loads('{}{} {', cls=ConcatJSONDecoder)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 339, in loads
return cls(encoding=encoding, **kw).decode(s)
File "decode.py", line 15, in decode
obj, end = self.raw_decode(s, idx=_w(s, end).end())
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 376, in raw_decode
obj, end = self.scan_once(s, idx)
ValueError: Expecting object: line 1 column 5 (char 5)
示例
>>> loads_invalid_obj_list('{}{}')
[{}, {}]
>>> loads_invalid_obj_list('{}{\n}{')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "decode.py", line 9, in loads_invalid_obj_list
obj, end = decoder.raw_decode(s, idx=end)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 376, in raw_decode
obj, end = self.scan_once(s, idx)
ValueError: Expecting object: line 2 column 2 (char 5)
>>> print json.loads('{}', cls=ConcatJSONDecoder)
[{}]
>>> print json.load(open('file'), cls=ConcatJSONDecoder)
[{}]
>>> print json.loads('{}{} {', cls=ConcatJSONDecoder)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 339, in loads
return cls(encoding=encoding, **kw).decode(s)
File "decode.py", line 15, in decode
obj, end = self.raw_decode(s, idx=_w(s, end).end())
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 376, in raw_decode
obj, end = self.scan_once(s, idx)
ValueError: Expecting object: line 1 column 5 (char 5)
打印json.loads(“{}”,cls=ConcatJSONDecoder)
[{}]
>>>打印json.load(打开('file'),cls=ConcatJSONDecoder)
[{}]
>>>print json.load('{}{}{',cls=ConcatJSONDecoder)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/_init__.py”,第339行,在loads中
返回cls(编码=编码,**千瓦)。解码
文件“decode.py”,第15行,在decode中
obj,end=self.raw\u decode(s,idx=\u w(s,end.end())
文件“/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py”,第376行,原始解码
obj,end=self.scan_一次(s,idx)
ValueError:应为对象:第1行第5列(字符5)
这将从字符串中解码JSON对象的“列表”:
from json import JSONDecoder
def loads_invalid_obj_list(s):
decoder = JSONDecoder()
s_len = len(s)
objs = []
end = 0
while end != s_len:
obj, end = decoder.raw_decode(s, idx=end)
objs.append(obj)
return objs
这里的好处是,您可以很好地使用解析器,因此它会不断准确地告诉您在哪里发现了错误
示例
>>> loads_invalid_obj_list('{}{}')
[{}, {}]
>>> loads_invalid_obj_list('{}{\n}{')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "decode.py", line 9, in loads_invalid_obj_list
obj, end = decoder.raw_decode(s, idx=end)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 376, in raw_decode
obj, end = self.scan_once(s, idx)
ValueError: Expecting object: line 2 column 2 (char 5)
>>> print json.loads('{}', cls=ConcatJSONDecoder)
[{}]
>>> print json.load(open('file'), cls=ConcatJSONDecoder)
[{}]
>>> print json.loads('{}{} {', cls=ConcatJSONDecoder)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 339, in loads
return cls(encoding=encoding, **kw).decode(s)
File "decode.py", line 15, in decode
obj, end = self.raw_decode(s, idx=_w(s, end).end())
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 376, in raw_decode
obj, end = self.scan_once(s, idx)
ValueError: Expecting object: line 1 column 5 (char 5)
示例
>>> loads_invalid_obj_list('{}{}')
[{}, {}]
>>> loads_invalid_obj_list('{}{\n}{')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "decode.py", line 9, in loads_invalid_obj_list
obj, end = decoder.raw_decode(s, idx=end)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 376, in raw_decode
obj, end = self.scan_once(s, idx)
ValueError: Expecting object: line 2 column 2 (char 5)
>>> print json.loads('{}', cls=ConcatJSONDecoder)
[{}]
>>> print json.load(open('file'), cls=ConcatJSONDecoder)
[{}]
>>> print json.loads('{}{} {', cls=ConcatJSONDecoder)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 339, in loads
return cls(encoding=encoding, **kw).decode(s)
File "decode.py", line 15, in decode
obj, end = self.raw_decode(s, idx=_w(s, end).end())
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 376, in raw_decode
obj, end = self.scan_once(s, idx)
ValueError: Expecting object: line 1 column 5 (char 5)
打印json.loads(“{}”,cls=ConcatJSONDecoder)
[{}]
>>>打印json.load(打开('file'),cls=ConcatJSONDecoder)
[{}]
>>>print json.load('{}{}{',cls=ConcatJSONDecoder)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/_init__.py”,第339行,在loads中
返回cls(编码=编码,**千瓦)。解码
文件“decode.py”,第15行,在decode中
obj,end=self.raw\u decode(s,idx=\u w(s,end.end())
文件“/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py”,第376行,原始解码
obj,end=self.scan_一次(s,idx)
ValueError:应为对象:第1行第5列(字符5)
像这样的东西怎么样