2010-10-22 2 views
1

J'ai un dictionnaire en Python que je voudrais sérialiser en JSON et convertir en une chaîne C appropriée pour qu'il contienne une chaîne JSON valide qui correspond à mon dictionnaire d'entrée. J'utilise le résultat pour générer automatiquement une ligne dans un fichier source C. Je l'ai? Voici un exemple:en utilisant Python pour générer un littéral de chaîne C de JSON

>>> import json 
>>> mydict = {'a':1, 'b': 'a string with "quotes" and \t and \\backslashes'} 
>>> json.dumps(mydict) 
'{"a": 1, "b": "a string with \\"quotes\\" and \\t and \\\\backslashes"}' 
>>> print(json.dumps(mydict)) 
{"a": 1, "b": "a string with \"quotes\" and \t and \\backslashes"} 

Ce que je dois générer est la chaîne C suivant:

"{\"a\": 1, \"b\": \"a string with \\\"quotes\\\" and \\t and \\\\backslashes\"}" 

En d'autres termes, je dois échapper à la barre oblique inverse et guillemet sur le résultat de l'appel JSON. décharges (mydict). Au moins, je pense que je fais ... Est-ce que ce qui suit fonctionnera? Ou est-ce que je manque un cas d'angle évident?

>>> s = '"'+json.dumps(mydict).replace('\\','\\\\').replace('"','\\"')+'"' 
>>> print s 
"{\"a\": 1, \"b\": \"a string with \\\"quotes\\\" and \\t and \\\\backslashes\"}" 
+0

Vous ne voulez pas définir un dictionnaire en C. Vous voulez une chaîne syntaxique C qui pourrait être analysée pour générer votre dictionnaire? Pourquoi ne pas finesse l'ensemble du problème en stockant le résultat dans un fichier et en chargeant le fichier lors de l'exécution? Alors vous n'avez pas à échapper à des trucs. – hughdbrown

+0

Je ne l'analyse pas en C. C'est un système embarqué où je transmets la chaîne verbatim à un PC, où la chaîne est analysée. –

+0

... et en fait ça va mieux, c'est aussi pour une directive DWARF qui cache la chaîne dans un fichier symbole. Je ne peux pas le faire en cours d'exécution; il n'y a pas de système de fichiers accessible à mon système embarqué. –

Répondre

2

chaîne AC commence par une citation et se termine par une citation, n'a pas nulls intégré, a toutes les citations intégrées se sont échappés avec Doseret, et tous backslash embarqués les littéraux sont doublés.

Alors prenez votre chaîne, doublez les barres obliques inverses et évitez les guillemets avec un antislash. Je pense que votre code est exactement ce dont vous avez besoin:

s = '"' + json.dumps(mydict).replace('\\', r'\\').replace('"', r'\"') + '"' 

Alternativement, vous pouvez opter pour cette version légèrement moins robuste:

def c_string(s): 
    all_chars = (chr(x) for x in range(256)) 
    trans_table = dict((c, c) for c in all_chars) 
    trans_table.update({'"': r'\"', '\\': r'\\'}) 
    return "".join(trans_table[c] for c in s) 

def dwarf_string(d): 
    import json 
    return '"' + c_string(json.dumps(d)) + '"' 

J'aimerais utiliser string.maketrans() mais une table de traduction peut mapper une caractère à au plus un seul caractère.

0

Peut-être que c'est ce que vous voulez:

repr(json.dumps(mydict)) 
+0

Non, car cela n'échappe pas au guillemet "" ' –

3

Votre suggestion originale et la réponse de hughdbrown semble correct pour moi, mais j'ai trouvé un peu plus courte réponse:

c_string = json.dumps(json.dumps(mydict)) 

script de test:

>>> import json 
>>> mydict = {'a':1, 'b': 'a string with "quotes" and \t and \\backslashes'} 
>>> c_string = json.dumps(json.dumps(mydict)) 
>>> print(c_string) 
"{\"a\": 1, \"b\": \"a string with \\\"quotes\\\" and \\t and \\\\backslashes\"}" 

qui ressemble exactement la bonne C chaîne que vous voulez.

(heureusement « json.dumps() » de Python passe en avant-barres obliques à travers tout droit sans changement -. Contrairement à certains codeurs JSON en préfixe de chaque barre oblique avec une barre oblique inverse tel que celui décrit à Processing escaped url strings within json using python).

+0

intéressant, c'est assez intelligent, je ne travaille plus sur ce projet et je n'ai plus accès au logiciel + cas de test, donc je peux ' t facilement l'essayer cependant. –

Questions connexes