246 votes

Python/Json:Attente d'un nom de propriété entre guillemets doubles

J'ai essayé de trouver un bon moyen de charger des objets JSON en Python. J'envoie ces données JSON :

{'http://example.org/about': {'http://purl.org/dc/terms/title': [{'type': 'literal', 'value': "Anna's Homepage"}]}}

vers le backend où il sera reçu sous forme de chaîne de caractères, puis j'ai utilisé la fonction json.loads(data) pour l'analyser.

Mais à chaque fois, j'ai obtenu la même exception :

ValueError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

J'ai cherché sur Google mais rien ne semble fonctionner à part cette solution. json.loads(json.dumps(data)) qui personnellement me semble peu efficace puisqu'il accepte tout type de données même celles qui ne sont pas au format json.

Toute suggestion sera très appréciée.

72 votes

Mon erreur n'était pas de mettre des guillemets doubles. J'ai ajouté une virgule après la dernière paire clé-valeur comme on le fait en python. Ce n'est pas le cas en JSON.

12 votes

toujours utiliser json.dumps() plutôt que d'écrire en python et d'espérer que la notation python fonctionnera dans votre lecteur JavaScript.

0 votes

J'ai rencontré ce problème parce que j'ai pris le résultat d'un print(jsonpickle_deserialized_object_string) et a essayé de l'utiliser. Pour une raison ou pour une autre print() modifie les citations de " à '

280voto

ElmoVanKielmo Points 3562

Ceci :

{
    'http://example.org/about': {
        'http://purl.org/dc/terms/title': [
            {'type': 'literal', 'value': "Anna's Homepage"}
        ]
     }
}

n'est pas JSON.
Ceci :

{
     "http://example.org/about": {
         "http://purl.org/dc/terms/title": [
             {"type": "literal", "value": "Anna's Homepage"}
          ]
      }
}

est JSON.

EDIT :
Certains commentateurs ont suggéré que ce qui précède n'était pas suffisant.
Spécification JSON - RFC7159 indique qu'une chaîne de caractères commence et se termine par des guillemets. C'est-à-dire " .
Quoute unique ' n'a pas de signification sémantique dans JSON et n'est autorisé qu'à l'intérieur d'une chaîne de caractères.

7 votes

Merci :) Je n'ai pas fait attention à cela, j'utilise le bon format json lors de l'envoi des données mais lorsqu'elles sont reçues par le backend, les guillemets doubles sont remplacés par des guillemets simples ! c'est pourquoi j'ai obtenu cette exception.

213 votes

Ce n'est pas une solution. Une solution lui indiquerait comment modifier la chaîne en json valide.

5 votes

@FistOfFury Je suis désolé mais votre déclaration est basée sur une fausse hypothèse selon laquelle une chaîne JSON arbitraire invalide peut être transformée de manière fiable par programme en une chaîne valide. De nombreuses réponses à cette question tentent de résoudre le problème en remplaçant ' par " et ainsi de suite. Dois-je vous donner des exemples simples de chaînes d'entrée qui brisent ces "solutions" ? Apparemment, l'OP a compris qu'il ne s'agit pas de JSON et a pu continuer - il a accepté ma réponse. Indice - la chaîne d'entrée ressemble davantage à la sortie de la méthode Python dict.__repr__().

125voto

elig Points 169

Comme JSON ne permet d'entourer les chaînes de caractères que de guillemets doubles, vous pouvez manipuler la chaîne comme suit :

str = str.replace("\'", "\"")

si votre JSON contient des guillemets simples échappés ( \' ), vous devez utiliser le code suivant, plus précis :

import re
p = re.compile('(?<!\\\\)\'')
str = p.sub('\"', str)

Cela remplacera toutes les occurrences de guillemets simples par des guillemets doubles dans la chaîne JSON. str et, dans ce dernier cas, ne remplacera pas les guillemets simples échappés.

Vous pouvez également utiliser js-beautify qui est moins stricte :

$ pip install jsbeautifier
$ js-beautify file.js

13 votes

Ce n'est pas une bonne idée car il peut remplacer tous les 's par des "s", ce qui est faux : EXEMPLE : 'it's bad' -> "it "s bad" -> chaîne malformée

1 votes

@Reihan_amn J'ai ajouté une alternative regex plus précise pour les cas où les guillemets simples échappés sont utilisés.

0 votes

Merci, j'utilise stackoverflow.com/a/63862387/1497139 au lieu de maintenant

10voto

Daniel Roseman Points 199743

Tout simplement, cette chaîne n'est pas un JSON valide. Comme l'indique l'erreur, les documents JSON doivent utiliser des guillemets doubles.

Vous devez déterminer la source des données.

1 votes

Que faire si vous n'avez pas le contrôle de la source des données ?...

0 votes

Il n'est pas toujours possible de dire "Vous devez corriger la source des données" lorsque vous travaillez dans une grande organisation. Parfois, vous avez des données légèrement malformées et vous devez les faire fonctionner.

9voto

Yaron Points 4877

J'ai vérifié vos données JSON

{'http://example.org/about': {'http://purl.org/dc/terms/title': [{'type': 'literal', 'value': "Anna's Homepage"}]}}

en http://jsonlint.com/ et les résultats ont été les suivants :

Error: Parse error on line 1:
{   'http://example.org/
--^
Expecting 'STRING', '}', got 'undefined'

En la modifiant pour obtenir la chaîne suivante, l'erreur JSON est résolue :

{
    "http://example.org/about": {
        "http://purl.org/dc/terms/title": [{
            "type": "literal",
            "value": "Anna's Homepage"
        }]
    }
}

4 votes

MERCI POUR CE LIEN !

7voto

alexbclay Points 794

Les chaînes JSON doivent utiliser des guillemets doubles. La bibliothèque python JSON applique cette règle, de sorte que vous ne pouvez pas charger votre chaîne. Vos données doivent ressembler à ceci :

{"http://example.org/about": {"http://purl.org/dc/terms/title": [{"type": "literal", "value": "Anna's Homepage"}]}}

Si ce n'est pas possible, vous pouvez utiliser ast.literal_eval() au lieu de json.loads()

3 votes

Il ne s'agit pas d'une restriction de la bibliothèque Python, mais du format JSON lui-même.

0 votes

Vous avez raison. Cependant, certains analyseurs JSON ne respectent pas les guillemets doubles. Je vais mettre à jour ma réponse.

0 votes

À condition que ce not-JSON ne contienne jamais de guillemets doubles à l'intérieur de chaînes à guillemets simples, tout ce que vous avez à faire est de substituer toutes les chaînes simples par des chaînes doubles avant d'invoquer json.loads()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X