使用Pythontokenize module将文本流转换为使用逗号而不是分号的文本流。 Python 分词器也很乐意处理 JSON 输入,甚至包括分号。分词器将字符串呈现为整个代币和“原始”分号在流中作为单个分号token.OP
供您替换的令牌:
import tokenize
import json
corrected = []
with open('semi.json', 'r') as semi:
for token in tokenize.generate_tokens(semi.readline):
if token[0] == tokenize.OP and token[1] == ';':
corrected.append(',')
else:
corrected.append(token[1])
data = json.loads(''.join(corrected))
这假设格式becomes用逗号替换分号后,JSON 有效;例如结束语之前没有尾随逗号]
or }
允许,尽管您甚至可以跟踪添加的最后一个逗号,并在下一个非换行符是右大括号时再次删除它。
Demo:
>>> import tokenize
>>> import json
>>> open('semi.json', 'w').write('''\
... {
... "client" : "someone";
... "server" : ["s1"; "s2"];
... "timestamp" : 1000000;
... "content" : "hello; world"
... }
... ''')
>>> corrected = []
>>> with open('semi.json', 'r') as semi:
... for token in tokenize.generate_tokens(semi.readline):
... if token[0] == tokenize.OP and token[1] == ';':
... corrected.append(',')
... else:
... corrected.append(token[1])
...
>>> print ''.join(corrected)
{
"client":"someone",
"server":["s1","s2"],
"timestamp":1000000,
"content":"hello; world"
}
>>> json.loads(''.join(corrected))
{u'content': u'hello; world', u'timestamp': 1000000, u'client': u'someone', u'server': [u's1', u's2']}
令牌间的空白已被删除,但可以通过注意来重新设置tokenize.NL
代币和(lineno, start)
and (lineno, end)
位置元组是每个标记的一部分。由于令牌周围的空格对于 JSON 解析器来说并不重要,因此我并没有为此烦恼。