Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove all last commas between brackets

Tags:

python

json

I'm trying to format the following as JSON (in Python):

{
   "sessionTimeout":"3600.0",
   "serverVersion":"LK_LK-NL-7_188-176-419",
   "worldDawn":"2018-10-09 06:00:00 Etc/GMT",
   "Data":{
      "Player":[
         {
            "nick":"Player11226400",
            "points":"44",
            "alliancePermission":"0",
            "isOnVacation":"false",
            "id":"5048",
            "rank":"561",
            "entityName":"Player",
         },
         {
            "nick":"Player11230580",
            "points":"15",
            "alliancePermission":"0",
            "isOnVacation":"false",
            "id":"5215",
            "rank":"2081",
            "entityName":"Player",
         },
         {
            "nick":"Player11291581",
            "points":"15",
            "alliancePermission":"0",
            "isOnVacation":"false",
            "id":"5942",
            "rank":"2081",
            "entityName":"Player",
         }
      ]
   }
}

Every JSON validator of course tells me that this is not valid JSON because of the trailing "," before each }, so I want to remove that comma. I tried removing them with .replace('"Player",", '"Player"') but I don't consider this as a good solution. This because I also have trailing "," in for example a Alliance or Habitat string ("Habitat", & "Alliance",)

Could anyone help me with finding a better solution to this problem?

like image 367
Sander Bakker Avatar asked Oct 08 '18 08:10

Sander Bakker


2 Answers

Two solutions:

First one, cool if your json file doesn't have null or false/true booleans would be to read the input using ast.literal_eval which can process those commas, then dump back the dict as json if needed:

d = ast.literal_eval(txt)
print(json.dumps(d,indent=4))

if you can't, you can use a regex to remove commas that happen before a newline if the next line starts with spaces + closing braces/brackets:

import re

print(json.loads(re.sub(",(\n\s+[\}\]])",r"\1",txt)))

here's a full snippet containing the 2 approaches with a cut-down version of your input:

import ast,json

txt = """{
   "sessionTimeout":"3600.0",
   "serverVersion":"LK_LK-NL-7_188-176-419",
   "worldDawn":"2018-10-09 06:00:00 Etc/GMT",
   "Data":{
      "Player":[
         {
            "nick":"Player11226400",
            "rank":"561",
            "entityName":"Player",
         },
         {
            "nick":"Player11230580",
            "rank":"2081",
            "entityName":"Player",
         },
         {
            "nick":"Player11291581",
            "rank":"2081",
            "entityName":"Player",
         }
      ]
   }
}"""

print("ast literal eval:")
d = ast.literal_eval(txt)
print(json.dumps(d,indent=4))

import re

print("regex:")
d = json.loads(re.sub(",(\n\s+[\}\]])",r"\1",txt))
print(json.dumps(d,indent=4))

both methods successfully parse your input file. The first method will work flawlessly as long as there are no null pointers & booleans, the second method may fail in some obscure formatting cases. In case of bad luck, you can hack something in between.

like image 134
Jean-François Fabre Avatar answered Sep 23 '22 19:09

Jean-François Fabre


Since JSON is a subset of YAML, where dangling commas are permitted, you can use a yaml parser here.

pip install pyyaml

The library has a load function, similar to the standard library json.loads.

import json, yaml
json.dumps(yaml.load(jsondata))

You can also use ast.literal_eval for this particular data. But unlike pyyaml that doesn't work if your json contains literal false, true or null values.

like image 31
Håken Lid Avatar answered Sep 22 '22 19:09

Håken Lid