Can json.loads ignore trailing commas?
Solution 1:
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
Solution 2:
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)
Solution 3:
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"}
Solution 4:
Fast forward to 2021, now we have https://pypi.org/project/json5/
A quote from the link:
A Python implementation of the JSON5 data format.
JSON5 extends the JSON data interchange format to make it slightly more usable as a configuration language:
- JavaScript-style comments (both single and multi-line) are legal.
- Object keys may be unquoted if they are legal ECMAScript identifiers
- Objects and arrays may end with trailing commas.
- Strings can be single-quoted, and multi-line string literals are allowed.
Usage is consistent with python's built in json module:
>>> import json5
>>> json5.loads('{"key1": "{my special value,}",}')
{u'key1': u'{my special value,}'}
It does come with a warning:
Known issues
- Did I mention that it is SLOW?
It is fast enough for loading start up config etc.