Le code suivant fonctionne sur python sans aucun problème. Il ouvre le fichier JSON et remplace toutes les bananes
par apples
:
replacements = """ArmReoriented", "visible": true""" : """ArmReoriented", "visible": false,"""
Cependant, je souhaite remplacer "ArmReoriented" , "visible": true
avec "ArmReoriented", "visible": false,
J'ai essayé d'utiliser des guillemets triples, mais cela ne fonctionne pas. p >
import json replacements = "banana" : "apple" with open(mycodepath, 'r') as file: data = file.read() for old, new in replacements.items(): data = data.replace(old, new)
Comment remplacer un texte contenant des guillemets sur JSON en utilisant Python?
3 Réponses :
Utiliser "" "est essentiellement un commentaire ou une chaîne de documents et ne fonctionnerait pas.
p> Mettez des guillemets entre une chaîne de guillemets simples comme ci-dessous.
replacements = {'"ArmReoriented", "visible": true' : '"ArmReoriented", "visible": false'}
Effectuer des remplacements textuels sur des données JSON n'est pas quelque chose que nous devrions jamais approuver. Il est intrinsèquement peu fiable - par exemple, le JSON pourrait être écrit sans espace non littéral, n'ayant donc pas d'espaces après les virgules, auquel cas le remplacement ne fonctionnerait pas. Ou il pourrait avoir des nouvelles lignes partout au lieu d'espaces blancs - toujours le même document littéral, mais un encodage différent afin que les tentatives de reconnaissance des sous-chaînes échouent.
@CharlesDuffy Dans ma réponse, je ne soutiens pas non plus la même chose. Ce que j'ai aidé OP est de créer un dict de clé de chaîne et de valeurs contenant des guillemets doubles.
@CharlesDuffy J'ai également voté pour le premier commentaire.
Essayez de passer aux guillemets simples dans votre dict de remplacements:
replacements = {"\"ArmReoriented\", \"visible\": true": "\"ArmReoriented\", \"visible\": false,"}
Vous pouvez également échapper des guillemets doubles à la fois de la clé et de la valeur dans votre dict de remplacement:
replacements = {'"ArmReoriented", "visible": true': '"ArmReoriented", "visible": false,'} data = 'asd asd asd "ArmReoriented", "visible": true asd asd' for old, new in replacements.items(): data = data.replace(old, new) print(data)
Si nous savons à quelle clé la valeur ArmReoriented
est attachée, nous pouvons le faire de la bonne manière, en traitant votre contenu données structurées plutôt que sous forme de chaîne:
def hideReorientedArm(obj): if isinstance(obj, dict): if obj.get("visible") is True: foundArmReoriented = False for (k,v) in obj.items(): if v == "ArmReoriented": foundArmReoriented = True break if foundArmReoriented: obj["visible"] = False return obj
Voir ceci en cours d'exécution sur https://ideone.com/ Zr6546
Même si vous ne connaissez pas le nom de la clé spécifique ayant cette valeur, vous pouvez toujours les rechercher si cela est nécessaire pour pour une raison quelconque, en remplaçant la définition plus courte hideReorientedArm
ci-dessus par quelque chose qui ressemble plus à ce qui suit:
import json, copy def hideReorientedArm(obj): if isinstance(obj, dict): if obj.get("LastEvent") == "ArmReoriented" and obj.get("visible") is True: obj["visible"] = False return obj def walk(obj, updateFn): if isinstance(obj, list): obj = [walk(elem, updateFn) for elem in obj] elif isinstance(obj, dict): obj = {k: walk(v, updateFn) for k, v in obj.items()} return updateFn(obj) with open(mycodepath, 'r') as file: data = json.load(file) data = walk(data, hideReorientedArm)
... voir cette version s'exécutant à https://ideone.com/z34Mx1
Ne manipulez jamais du texte JSON brut! Vous avez écrit
import json
mais vous ne l'utilisez jamais!Vous pouvez inclure les guillemets doubles dans les chaînes que vous passez
replace ()
en les spécifiant comme ceci:'"banane"'
et'"apple"' code>.
Pouvez-vous nous donner plus de détails sur votre document JSON, afin que nous sachions à quelle clé la valeur
ArmReoriented
est associée?@Gustavo, ... personnellement, je n'utiliserais pas Python pour ce travail. C'est un one-liner dans jq. En supposant que
ArmReoriented
est la valeur associée à une cléLastEvent
(juste pour choisir quelque chose au hasard):jq 'walk (si type == "object" et. ["LastEvent"] == "ArmReoriented" et. ["Visible"] == true then. ["Visible"] = false else. End) '
fera l'affaire.Notez que JSON ne garantit pas un ordre de sérialisation! Ce n'est pas parce qu'une fois que vous écrivez votre fichier, il dit
{"A": "B", "C": "D"}
que ce ne sera pas{"C" : "D", "A": "B"}
la prochaine fois, donc tout code qui suppose que"B"
viendra toujours avant"C" code > est bogué.
@CharlesDuffy, je suis un débutant total en programmation. Je viens de mon code python pour changer le code JSON à partir d'un modèle, que je télécharge ensuite le code dans son ensemble pour créer la page. Je ne vois pas pourquoi la manipulation du texte JSON brut est si mauvaise parce que ce n'est apparemment qu'un document texte avant le téléchargement.
@Gustavo car les clés de dictionnaire ne sont pas ordonnées et en fonction du sérialiseur JSON, l'ordre peut changer et casser votre code. Sans parler des espaces et de l'indentation. C'est une mauvaise pratique car elle est très fragile. De plus, il est 10 fois plus facile d'analyser le JSON, de le modifier, puis de le redéfinir en texte.
@Gustavo, ... juste pour ajouter un peu de saveur à ce que disait Gillespie - il était une fois, j'ai travaillé pour une startup web, et l'une des choses qui a fait une énorme quantité de travail autrement inutile était les clients qui utilisaient ce genre de la technique que vous montrez ici, "parser" le contenu JSON sous forme de chaînes - parce que lorsque nous avons changé l'API d'une manière qui n'aurait pas cassé un véritable analyseur conforme, cela a cassé leur code, ils se plaindraient donc toujours lorsqu'une nouvelle fonctionnalité que nous ajoutions rompait leurs flux de travail créés à la main.
@Gustavo, ... pour vous donner un exemple, disons qu'un jour, au lieu du JSON disant
{"action": "ArmReoriented", "visible": true}
il dit{"action": "ArmReoriented", "timestamp": "2019-01-01T15: 36: 01", "visible": true}
. L'ajout d'un champtimestamp
ne ferait aucune différence pour un analyseur conforme , mais soudainement "visible" ne vient plus juste après"ArmReoriented"
, donc cela briserait la logique dont vous parlez ici.