我的文件包含不正确的JSON,我想通过将其放入正确分组的块来开始修复。
大括号分组{{ {} {} } } {{}} {{{}}}
应该已经是正确的
如何将所有顶级括号(正确分组)作为单独的字符串抓取?
答案 0 :(得分:2)
如果你不想安装任何额外的模块,简单的功能就是:
def top_level(s):
depth = 0
start = -1
for i, c in enumerate(s):
if c == '{':
if depth == 0:
start = i
depth += 1
elif c == '}' and depth:
depth -= 1
if depth == 0:
yield s[start:i+1]
print(list(top_level('{{ {} {} } } {{}} {{{}}}')))
输出:
['{{ {} {} } }', '{{}}', '{{{}}}']
它会跳过无效的大括号,但可以轻松修改,以便在发现错误时报告错误。
答案 1 :(得分:1)
使用regex
module:
In [1]: import regex
In [2]: braces = regex.compile(r"\{(?:[^{}]++|(?R))*\}")
In [3]: braces.findall("{{ {} {} } } {{}} {{{}}}")
Out[3]: ['{{ {} {} } }', '{{}}', '{{{}}}']
答案 2 :(得分:1)
pyparsing
在这里真的很有帮助。它会处理你在字符串里面有大括号等的病态案例。自己完成所有这些工作可能有点棘手,但幸运的是,某人(图书馆的作者)已经完成了hard stuff for us...。我将在这里重现代码以防止链接腐烂:
# jsonParser.py
#
# Implementation of a simple JSON parser, returning a hierarchical
# ParseResults object support both list- and dict-style data access.
#
# Copyright 2006, by Paul McGuire
#
# Updated 8 Jan 2007 - fixed dict grouping bug, and made elements and
# members optional in array and object collections
#
json_bnf = """
object
{ members }
{}
members
string : value
members , string : value
array
[ elements ]
[]
elements
value
elements , value
value
string
number
object
array
true
false
null
"""
from pyparsing import *
TRUE = Keyword("true").setParseAction( replaceWith(True) )
FALSE = Keyword("false").setParseAction( replaceWith(False) )
NULL = Keyword("null").setParseAction( replaceWith(None) )
jsonString = dblQuotedString.setParseAction( removeQuotes )
jsonNumber = Combine( Optional('-') + ( '0' | Word('123456789',nums) ) +
Optional( '.' + Word(nums) ) +
Optional( Word('eE',exact=1) + Word(nums+'+-',nums) ) )
jsonObject = Forward()
jsonValue = Forward()
jsonElements = delimitedList( jsonValue )
jsonArray = Group(Suppress('[') + Optional(jsonElements) + Suppress(']') )
jsonValue << ( jsonString | jsonNumber | Group(jsonObject) | jsonArray | TRUE | FALSE | NULL )
memberDef = Group( jsonString + Suppress(':') + jsonValue )
jsonMembers = delimitedList( memberDef )
jsonObject << Dict( Suppress('{') + Optional(jsonMembers) + Suppress('}') )
jsonComment = cppStyleComment
jsonObject.ignore( jsonComment )
def convertNumbers(s,l,toks):
n = toks[0]
try:
return int(n)
except ValueError, ve:
return float(n)
jsonNumber.setParseAction( convertNumbers )
唷!那是很多......现在我们如何使用它?这里的一般策略是扫描字符串中的匹配项,然后将这些匹配项从原始字符串中切片。每个扫描结果都是(lex-tokens, start_index, stop_index)
形式的元组。对于我们的使用,我们不关心lex-tokens,只关注开始和停止。我们可以这样做:string[result[1], result[2]]
它会起作用。我们也可以string[slice(*result[1:])]
- 选择。
results = jsonObject.scanString(testdata)
for result in results:
print '*' * 80
print testdata[slice(*result[1:])]