J'utilise des rails 4.2.3. Je parcaie Json envoyé par un tiers (je ne contrôle pas comment ce Json est formé). J'ai remarqué que les taht ils envoient très parfois mal Json, comme si remarque dans ce qui précède, le mot "graisse", avec les guillemets, vissait le reste du JSON. Dans mon code de rails, je analysais le Json, comme ... p> Bien que je puisse prendre des erreurs lorsque JSON ne pars pas correctement, je me demande s'il y a une façon de rendre compte de ces citations mal placées, corrigez-les de manière à ce que la chaîne ci-dessus ne constitue pas un mauvais JSON, puis analyser correctement le JSON. P> P>
7 Réponses :
Si vous savez exactement quelles malformations pourraient survenir, vous pourriez réussir à faire des solutions de contournement folle comme à l'aide de RegEx pour correspondre et corrigez la chaîne avant de l'analyser comme JSON:
(?:")([^,:"]*"[^,:"]*"[^,:"]*)(?:")
Merci. Mon knwoeldge d'expression et de rails réguliers est encore un peu limité. Je vois que cette exécressive identifie les mauvaises citations, mais comment puis-je utiliser ceci pour résoudre la situation?
@Mike - J'ai ajouté un POP complet dans le message d'origine.
Bonne affaire. Comme j'utilise des rails pour le faire (par opposition à JS), comment cela jouerait-il à ROR?
@Mike - Désolé, je ne suis actuellement aucune raille qui parle. Ma réponse n'a pas été intégrée comme une solution mise en œuvre complète de toute façon. Je voulais juste vous montrer comment vous pourriez résoudre le problème. Fondamentalement, ce sera la même chose dans Ruby sur les rails de toute façon, juste une syntaxe différente.
Essayez de manipuler une erreur en utilisant Commencer la manipulation d'exception de sauvetage comme, Ceci augmentera une exception lorsqu'un format JSON est invalide et informer le propriétaire de la source pour modifier le JSON. P> P> P> P> P> P> P> P> P> P> >
Je ne comprends pas comment cette réponse m'aidera à détecter les types de malformations de devis que j'ai décrites et que je les fixe davantage.
Utilisation de regex, vous pouvez vérifier avant d'analyser les guillemets \ "\" code> suivi d'un mot
\ w + code> et finissant par
\ " code>. Si vous trouvez qu'il utilise
gsub code> pour remplacer la phrase avec des guillemets simples et un lookback
"\ '\\ 1 \' code>.
t='{"DisplayName":""fat" Tony Elvis ","Time":null,"OverallRank":19,"AgeRank":4}'
t=t.gsub(/\"\"(\w+)\"/, '"\'\\1\'')
Je pense que vous devez faire / avoir certains hypothèses em> sur le "JSON" toujours vrai. Si, par exemple, les objets JSON ont toujours un ordre fixe d'attributs, cela pourrait aider beaucoup, surtout si seuls les attributs simples sont problématiques. J'essaierais de faire correspondre p> Ensuite, remplacez-la à l'aide d'une fonction de "fixateur", qui utilise probablement simplement les groupes de capture et réécrit certains objet créé par ad-hoc en réellement valide JSON valide. Une variation serait, d'élargir le Cependant, toute l'approche devient plus compliquée avec des attributs facultatifs et encore plus avec un ordre flexible d'attributs (tous pourraient toujours être gérables). P> Comme vous l'avez très bien pu remarquer, cela ne fonctionne que si l'hypothèse en haut est vraie. Selon les hypothèses que vous pouvez faire, la solution peut être très simple. Cependant, tout devient difficile à manier, si ces éléments mal formés sont complètement irréguliers. Alors ... bonne chance, je suppose. Veuillez poster les hypothèses sur le JSON que vous croyez être vraie, si vous avez besoin d'une aide supplémentaire. S'il n'y en a pas cependant, un programme devra deviner em>, ce que nous voulions dire. Je veux dire, quelqu'un pourrait em> signifie: p> si les guillemets sont échappés de manière erronée, vous auriez un problème. Mais comme je l'ai dit, vous devez faire certains em> hypothèse sur le "JSON". Je veux dire, l'hypothèse habituelle à propos de JSON est que c'est valable, car sinon, ce n'est tout simplement pas JSON. P> P> (. *?) Code> pour ne correspond à quelque chose que quelque chose est faux. P>
Ce n'est pas un problème facile à résoudre. Surtout parce que la rédaction d'un analyseur JSON n'est pas triviale et là, je doute que vous puissiez adapter un analyseur pour travailler comme vous le souhaitez. P>
Si je devais absolument résoudre ce problème par programme (comme appellé à demander au vendeur de réparer leur JSON), je le ferais probablement avec une ramification. P>
Prendre votre exemple String JSON: Écoutez d'abord l'entrée dans des personnages et itérez-les sur eux. Chaque fois qu'un devis est rencontré recueil et testez les deux possibilités: la citation fait partie du JSON et la citation fait partie des données. P>
Chaque fois que vous trouvez une citation, vous branchez, alors après deux devis, il y aura quatre solutions valides possibles, après quatre citations, il y aura 16 solutions possibles, etc. P>
{"DisplayName": "" Fat "Tony Elvis", "Time": NULL, "GallRank": 19, "Agerank": 4} Code> P>
En ce qui concerne les mauvaises citations est concernée, ce http://rubular.com/r/ybfcjycf6d p> Cela ne réalise pas les citations non appariées, cependant. p> p> regex_pattern code> doit pouvoir le remplacer par
\ " code>. Voici un échantillon de rails SNIPPET:
regex_pattern = /(?<=[^\[{:,\\]|")"(?=[^:,\}\]])/
corrected_content_str = content_str.gsub(regex_pattern, '\\"')
(? . LI>
(? = [^:, \} \]]]) Code>. Li>
ul>
Comme les autres affiches ont mentionné, si votre service ne vous fournit pas JSON valide, il n'ya aucun moyen de vous assurer que vous pourrez lire les données qu'ils vous envoient. Ce que vous pouvez faire cependant, est de trouver des cas courants et d'essayer de corriger ceux-ci.
Si vos documents JSON suivent le schéma de votre exemple, écrire un petit analyseur vous aidera à essayer de lire des documents malformés qui y adhèrent. p>
invalid = '{"DisplayName":""fat" Tony" Elvis","Time":null,"OverallRank":19,"AgeRank":4}'
# strip away { and }
tailhead = invalid[1..-2]
props = tailhead.split(/,(?=".+"\s*:)/)
pairs = props.map {|p| p.split(/:(?=(?:".*"|\d+|null|false|true)$)/i)}
escaped = pairs.map do |k,v|
# is this a string property?
string = v[/^"(.*?)"$/, 1]
string ? [k, "\"#{string.gsub(/"/,'\\"')}\""] : [k,v]
end
valid = '{' + escaped.map {|p| p.join(':')}.join(',') + '}'
json_data = JSON.parse(valid)
Bien sûr, vous pouvez essayer de corriger le JSON, mais que feriez-vous avec
{"A": "," B ": 1"} code>. Vous ne devriez pas accepter JSON invalide, car il n'est pas propre et imprévisible et vous pouvez simplement vous échapper. par exemple.
\ "gras \" code> serait valide.
Je voudrais corriger le JSON mal formé (de la manière dont j'ai décrit ci-dessus) si possible. Si Taht n'est pas possible, c'est une réponse aussi.
Vous auriez essentiellement besoin de faire votre propre fixateur JSON. Peut-être diviser la chaîne où vous trouvez
"," code> et d'autres variations avec des espaces / nouvelles lignes entre, puis prenez tout après chaque
: code>, prenez la première et la dernière double citation et enfin remplacer chaque double citation par un seul, par exemple. Ensuite, vous pourriez l'utiliser dans l'analyseur. Une autre manière serait de contacter le fournisseur JSON et de leur demander de bien vouloir fournir un JSON valide.