web-dev-qa-db-fra.com

Supprimer toutes les dernières virgules entre parenthèses

J'essaie de formater le texte suivant en JSON (en 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",
         }
      ]
   }
}

Bien entendu, chaque validateur JSON me dit que ce n'est pas un JSON valide en raison de la fin du caractère "," avant chaque}, aussi je veux supprimer cette virgule. J'ai essayé de les supprimer avec .replace ('' Player ",", "" Player "') mais je ne considère pas cela comme une bonne solution, car j'ai également un", "suivi, par exemple dans une chaîne Alliance ou Habitat ("Habitat", & "Alliance",) 

Quelqu'un pourrait-il m'aider à trouver une meilleure solution à ce problème? 

7
Sander Bakker

Deux solutions:

Tout d’abord, cool si votre fichier json n’a pas null ou false/true booleans: lisez l’entrée en utilisant ast.literal_eval qui peut traiter ces virgules, puis relancez le dict en json si nécessaire:

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

si vous ne le pouvez pas, vous pouvez utiliser une expression rationnelle pour supprimer les virgules avant une nouvelle ligne si la ligne suivante commence par des espaces + des accolades/crochets de fermeture:

import re

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

voici un extrait complet contenant les 2 approches avec une version simplifiée de votre entrée:

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))

les deux méthodes analysent avec succès votre fichier d'entrée. La première méthode fonctionnera parfaitement tant qu’il n’y aura pas de pointeurs et de booléens nuls, la seconde méthode peut échouer dans certains cas de mise en forme obscurs. En cas de malchance, vous pouvez pirater quelque chose entre les deux.

7

Comme JSON est un sous-ensemble de YAML, où les virgules flottantes sont autorisées, vous pouvez utiliser un analyseur yaml ici. 

pip install pyyaml

La bibliothèque a une fonction load, similaire à la bibliothèque standard json.loads.

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

Vous pouvez également utiliser ast.literal_eval pour ces données particulières. Mais contrairement à pyyaml, cela ne fonctionne pas si votre json contient des valeurs littérales false, true ou null

6
Håken Lid

Utilisez le module json de python pour exporter python dict en json valide:

import json
json.dumps(<your-dict>)
0
Sanchit