As mentioned in this StackOverflow question, you are not allowed to have any trailing commas in json. For example, this
{
\"key1\": \"value1\",
\"key
Strip the commas before you pass the value in.
import re
def clean_json(string):
string = re.sub(",[ \t\r\n]+}", "}", string)
string = re.sub(",[ \t\r\n]+\]", "]", string)
return string
Cobbling together the knowledge from a few other answers, especially the idea of using literal_eval
from @Porkbutts answer, I present a wildly-evil solution to this problem
def json_cleaner_loader(path):
with open(path) as fh:
exec("null=None;true=True;false=False;d={}".format(fh.read()))
return locals()["d"]
This works by defining the missing constants to be their Pythonic values before evaluating the JSON struct as Python code. The structure can then be accessed from locals()
(which is yet another dictionary).
This should work with both Python 2.7 and Python 3.x
BEWARE this will execute whatever is in the passed file, which may do anything the Python interpreter can, so it should only ever be used on inputs which are known to be safe (ie. don't let web clients provide the content) and probably not in any production environment.
This probably also fails if it's given a very large amount of content.
In python you can have trailing commas inside of dictionaries and lists, so we should be able to take advantage of this using ast.literal_eval:
import ast, json
str = '{"key1": "value1", "key2": "value2",}'
python_obj = ast.literal_eval(str)
# python_obj is {'key1': 'value1', 'key2': 'value2'}
json_str = json.dumps(python_obj)
# json_str is '{"key1": "value1", "key2": "value2"}'
However, JSON isn't exactly python so there are a few edge cases to this. For example, values like null, true, false don't exist in python. We can replace those with valid python equivalents before we run the eval:
import ast, json
def clean_json(str):
str = str.replace('null', 'None').replace('true', 'True').replace('false', 'False')
return json.dumps(ast.literal_eval(str))
This will unfortunately mangle any strings that have the words null, true, or false in them.
{"sentence": "show your true colors"}
would become
{"sentence": "show your True colors"}
You can wrap python's json parser with jsoncomment
JSON Comment allows to parse JSON files or strings with:
- Single and Multi line comments
- Multi line data strings
- Trailing commas in objects and arrays, after the last item
Example usage:
import json
from jsoncomment import JsonComment
with open(filename) as data_file:
parser = JsonComment(json)
data = parser.load(data_file)