我正在解析包含 json 对象的文件。问题是某些文件在一行中有多个对象。例如:
{"data1": {"data1_inside": "bla{bl\"a"}}{"data1": {"data1_inside": "blabla["}}{"data1": {"data1_inside": "bla{bla"}}{"data1": {"data1_inside": "bla["}}
Run Code Online (Sandbox Code Playgroud)
我制作了一个函数,当没有左括号时尝试解析子字符串,但值中可能有大括号。我尝试通过检查引号的开头和结尾来跳过值,但也有带有转义引号的值。关于如何处理这个问题的任何想法?
我的尝试:
def get_lines(data):
lines = []
open_brackets = 0
start = 0
is_comment = False
for index, c in enumerate(data):
if c == '"':
is_comment = not is_comment
elif not is_comment:
if c == '{':
if not open_brackets:
start = index
open_brackets += 1
if c == '}':
open_brackets -= 1
if not open_brackets:
lines.append(data[start: index+1])
return lines
Run Code Online (Sandbox Code Playgroud)
Car*_*han 10
您可以使用 json raw_decoder!这允许在第一个 json 对象之后读取带有额外数据的 json 字符串。一个使用示例是:
>>> dec = json.JSONDecoder()
>>> json_str = '{"data": "Foo"}{"data": "BarBaz"}{"data": "Qux"}'
>>> dec.raw_decode(json_str)
({u'data': u'Foo'}, 15)
>>> dec.raw_decode(json_str[15:])
({u'data': u'BarBaz'}, 18)
>>> dec.raw_decode(json_str[33:])
({u'data': u'Qux'}, 15)
Run Code Online (Sandbox Code Playgroud)
元组的第一部分是 json 对象,第二部分是读取它时使用了多少字符串。因此,像这样的循环将允许您遍历字符串中的所有 json 对象。
dec = json.JSONDecoder()
pos = 0
while not pos == len(str(json_str)):
j, json_len = dec.raw_decode(str(json_str)[pos:])
pos += json_len
# Do something with the json j here
Run Code Online (Sandbox Code Playgroud)
简单但不太健壮的版本:
>>> import re
>>> s = r'{"data1": {"data1_inside": "bla{bl\"a"}}{"data1": {"data1_inside": "blabla["}}{"data1": {"data1_inside": "bla{bla"}}{"data1": {"data1_inside": "bla["}}'
>>> r = re.split('(\{.*?\})(?= *\{)', s)
['', '{"data1": {"data1_inside": "bla{bl\\"a"}}', '', '{"data1": {"data1_inside": "blabla["}}', '', '{"data1": {"data1_inside": "bla{bla"}}', '{"data1": {"data1_inside": "bla["}}']
Run Code Online (Sandbox Code Playgroud)
}{如果包含在字符串中,这将失败
正如其他人所建议的,您可以尝试解析每个元素。如果它无效,那么我们应该将该元素与下一个元素一起检查。
请注意,这r是上面代码的结果
accumulator = ''
res = []
for subs in r:
accumulator += subs
try:
res.append(json.loads(accumulator))
accumulator = ''
except:
pass
Run Code Online (Sandbox Code Playgroud)