En Python, existe-t-il un moyen de vérifier si une chaîne est un JSON valide avant d'essayer de l'analyser?
Par exemple, avec l'API Graph de Facebook, elle renvoie parfois du JSON, parfois un fichier image.
import json
def is_json(myjson):
try:
json_object = json.loads(myjson)
except ValueError as e:
return False
return True
Quelles impressions:
print is_json("{}") #prints True
print is_json("{asdf}") #prints False
print is_json('{ "age":100}') #prints True
print is_json("{'age':100 }") #prints False
print is_json("{\"age\":100 }") #prints True
print is_json('{"age":100 }') #prints True
print is_json('{"foo":[5,6.8],"foo":"bar"}') #prints True
Convertit une chaîne JSON en un dictionnaire Python:
import json
mydict = json.loads('{"foo":"bar"}')
print(mydict['foo']) #prints bar
mylist = json.loads("[5,6,7]")
print(mylist)
[5, 6, 7]
Convertit un objet python en chaîne JSON:
foo = {}
foo['gummy'] = 'bear'
print(json.dumps(foo)) #prints {"gummy": "bear"}
Si vous souhaitez accéder à l'analyse syntaxique de bas niveau, n'utilisez pas la vôtre, utilisez une bibliothèque existante: http://www.json.org/
Grand tutoriel sur python module JSON: https://pymotw.com/2/json/
Sudo cpan JSON::XS
echo '{"foo":[5,6.8],"foo":"bar" bar}' > myjson.json
json_xs -t none < myjson.json
Impressions:
, or } expected while parsing object/hash, at character offset 28 (before "bar}
at /usr/local/bin/json_xs line 183, <STDIN> line 1.
json_xs
est capable de vérifier, d’analyser, de prittifier, de coder, de décoder et plus encore la syntaxe:
Je dirais que l’analyse est la seule façon de vraiment dire. Les exceptions seront déclenchées par la fonction json.loads()
de python (presque certainement) si ce n'est pas le bon format. Cependant, aux fins de votre exemple, vous pouvez probablement simplement vérifier les deux premiers caractères non blancs.
Je ne connais pas bien le JSON que facebook renvoie, mais la plupart des chaînes JSON des applications Web commencent par un crochet vide [
ou bouclé {
. Je ne connais aucun format d'image qui commence par ces caractères.
Inversement, si vous connaissez les formats d'image susceptibles d'être affichés, vous pouvez vérifier le début de la chaîne pour en savoir plus sur les signatures permettant d'identifier les images et présumer que vous disposez du format JSON s'il ne s'agit pas d'une image.
Un autre moyen simple d'identifier un graphique, plutôt qu'une chaîne de texte, dans le cas où vous cherchez un graphique, consiste simplement à tester les caractères non-ASCII dans la première vingtaine de caractères de la chaîne (en supposant que le JSON est ASCII ).
J'ai proposé une solution générique et intéressante à ce problème:
class SafeInvocator(object):
def __init__(self, module):
self._module = module
def _safe(self, func):
def inner(*args, **kwargs):
try:
return func(*args, **kwargs)
except:
return None
return inner
def __getattr__(self, item):
obj = getattr(self.module, item)
return self._safe(obj) if hasattr(obj, '__call__') else obj
et vous pouvez l'utiliser comme ceci:
safe_json = SafeInvocator(json)
text = "{'foo':'bar'}"
item = safe_json.loads(text)
if item:
# do something