9
votes

Expression régulière pour ajouter des citations doubles autour des touches de JavaScript

J'utilise la fonction Getjson de JQuery pour faire une demande et gérer la réponse JSON. Le problème est la réponse que je récupère est mal formée et je ne peux pas le changer. La réponse ressemble à ceci comme suit:

{
    "aNumber": 200,    
    "someText": "'hello' world",
    "anObject": {
        "foo": "fooValue",
        "bar": "10.0"
    } 
}


1 commentaires

J'ai écrit une fonction de conversion dans une autre question , en utilisant des expressions régulières simples et n'a pas besoin eval () .


5 Réponses :


2
votes

edit - est revenu à signaler, tout d'abord, que ce n'est pas un problème qui peut être résolu avec une expression régulière.

Il est important de distinguer la notation JSON en tant que sérialisée. formulaire et notation de constante d'objet JavaScript.

ceci: xxx

est une valeur JavaScript parfaitement valide (fragment d'expression), de sorte que ceci: xxx

vous donne exactement le même résultat que: xxx

en d'autres termes, la valeur de "Y" dans l'une ou l'autre de ces les cas seront exactement les mêmes. Complètement, exactement la même chose, de sorte qu'il ne serait pas possible de dire que ces deux constantes ont été utilisées pour initialiser "y".

maintenant, si ce que vous voulez faire est de traduire un String contenant style JavaScript "JSON SHOWAND" sans citations en JSON valide, la seule chose à faire est d'analyser et de reconstruire la chaîne avec des citations autour des noms de propriété. C'est-à-dire que vous devrez écrir votre propre analyseur JSON "décontracté" que peut faire face à des identifiants non coqués en tant que noms de propriété, sinon trouver un analyseur hors tension pouvant gérer une syntaxe aussi détendue.

Dans votre cas, on dirait une fois que vous avez l'analyseur "détendu" disponible, vous avez terminé; Il ne devrait pas y avoir de besoin de vous traduire. Heureusement, votre réponse JSON "non valide" est totalement interprétable par JavaScript lui-même, donc si vous faites confiance à la source de données (et c'est un gros "si"), vous devriez pouvoir l'évaluer avec "eval () ".


0 commentaires

1
votes

upd 2020: L'objet que vous avez est un objet JavaScript valide , mais pas 100% valide JSON .

Un moyen facile de le convertir en JSON valide consiste à utiliser les fonctions JavaScript vous fournit, json.stringify : xxx

Vous pouvez exécuter ceci dans la console JS de votre navigateur.

Pour obtenir le formaté (alias "jolie-imprimé"), vous pouvez passer deux Arguments à cette fonction - le remplaçant (une fonction qui vous permet de filtrer certaines des propriétés de votre objet; juste passer un null si vous ne vous souciez pas) et espace (soit le nombre d'espaces ou une chaîne string qui sera placé avant chaque paire de valeurs de clé de votre objet 'String Représentation): < / p> xxx

dans votre cas e, cet appel xxx

vous donnera xxx Vous ** Ne devez pas faire cela - vous avez déjà un objet valide ** JSON **. Lire 'Bout Json [ici] [1]. Si vous avez besoin d'obtenir de la valeur, vous écrivez simplement `Data.watever` et cela fonctionne simplement. E.g.: Si vous avez JSON ** objet ** `Data`: { Moo: "foo", foo: "bar" } Tous les champs possibles sont `moo` et` foo` et leur utilisation sont respectivement `data.moo` et` data.foo`. Et si vous souhaitez utiliser `Data` comme un argument de jQuery, vous venez de le transmettre comme:` $ .charger ("http://my.site.com/moo", données, fonction (réponse) {/ * ... * /}) `. ** Remarque: ** Dans le dernier exemple que j'ai mentionné, la réponse sera une chaîne. Pour en faire un objet JSON valide, utilisez `$ .parsjson (réponse);` méthode.


5 commentaires

Il reçoit déjà une chaîne de réponse de son serveur. Le problème est que la chaîne est pas JSON valide. C'est cependant valide JavaScript.


@Pointy, voici quelques démonstration: jsfiddle.net/kbzu5 . S'il vous plaît, montre-moi où je me trompe. Ou peut-être que j'ai mal compris?


Dans la véritable notation JSON, noms de propriété - Les identificateurs du côté gauche des colons - doivent être cités . Tous les citations doivent être effectués avec des caractères à double citation ("), pas des caractères à une seule citation. Voir JSON.org pour plus info. C'est un sous-ensemble de la syntaxe littérale d'objet JavaScript.


C'est une réponse utile. Bien que je n'ai pas techniquement d'un objet JSON valide, j'ai valide JavaScript. Je ne serais pas en mesure d'utiliser JQuery's Parsejson car Parsejson attend un Json bien formé. Mais, je serais en mesure d'exécuter la réponse via la fonction EVAL pour utiliser data.moo ou data.foo.


@Evil e, eh bien, je suis content que cela vous ait aidé! =)



0
votes

Étant donné que c'est un "json" mal formé, vous ne pourrez pas utiliser jquery.getjson.

Vous pouvez utiliser xxx


3 commentaires

Bien que, en utilisant un bloc «eval» puisse être vulnérable et peut accueillir des problèmes de sécurité. Vous pouvez très bien utiliser JSON Parser comme ---- JSON.PARSE (JSontext) pour obtenir l'objet JSON au lieu d'EVAL


Le problème est que le texte brut est pas JSON valide.


C'est une excellente solution de travail et très proche de ce que j'ai mis en œuvre après avoir lu la réponse de @pointy. J'ai utilisé la fonction JQuery.ajax, mais j'ai explicitement défini le type de données comme «texte». Il n'y avait pas non plus besoin de remplacer les citations.



12
votes

J'essayais de résoudre le même problème à l'aide d'une regex dans JavaScript. J'ai une application écrite pour Node.js pour analyser JSON, mais je voulais une version "détendue" de l'analyseur (voir les commentaires suivants), car il n'est pas pratique de mettre des citations autour de chaque clé (nom). Voici ma solution: xxx

Voici une ventilation de la regex:

  • ({|,) recherche le début de l'objet, un { pour des objets plats ou , pour des objets embarqués.
  • (?: \ s *) trouve mais ne se souvient pas de l'espace blanc
  • (?: ')? trouve mais ne se souvient pas d'une seule citation (à remplacer par une double citation plus tard). Il y aura soit zéro ou l'un d'entre eux.
  • ([a-za-z _ $ \ \.] [A-ZA-Z0-9_ \ - \. $] *) est le nom (ou la touche). Commence par une lettre, un trait de soulignement, $ ou un point, suivi de caractères zéro ou plus alpha-numériques ou de soulignement ou de tirets ou de points ou de points ou $.
  • Le dernier caractère : est ce qui délimite le nom de l'objet de la valeur.

    Nous pouvons utiliser remplacer () avec un peu de vinaigrette pour obtenir nos clés nouvellement citées: xxx

    où le 1 $ est soit { ou , selon que l'objet a été incorporé dans un autre objet. \ " ajoute une double citation. 2 $ est le nom. \" une autre double citation. et enfin : la finit. Testez-le avec xxx

    sortie: xxx

    quelques commentaires:

    • Je n'ai pas testé cette méthode de vitesse, mais d'après ce que je rassemble en lisant certaines de ces entrées, c'est que l'utilisation d'une regex est plus rapide que eval ()
    • Pour ma demande, je limite les caractères que les noms sont autorisés avec ([A-ZA-Z _ $ \.] [A-ZA-Z0-9_ \ - \. $] *) pour ma version "détendue" Parser JSON. Si vous vouliez autoriser plus de caractères dans les noms (vous pouvez le faire et avoir toujours valide JSON), vous pouvez plutôt utiliser ([^ '":] +) pour signifier autre chose que les guillemets doubles ou simples ou un point de côlon. Cela vous limiterait toujours plus loin que la norme JSON (qui permet des guillemets simples dans le nom), mais vous ne seriez pas en mesure d'analyser avec cette méthode. Vous pouvez avoir toutes sortes de choses ici avec cette expression < code> ([^ '":] +) , soyez donc prudent.

      espère que cela aide.


2 commentaires

C'est une solution «assez bonne» pour de nombreuses situations. Mais s'il vous plaît ne vous trompez pas en pensant que toute expression régulière sera en mesure de gérer toutes les intrants. Par exemple, considérons ce qui se passe lorsque cette regex est nourrie cette entrée: {"sillypalue": "{hey: là}"}


et aussi il laisse l'espace de fuite {nom: "valeur"} => {"nom_": "valeur"}



15
votes

Cette regex fera le tour xxx

C'est un PHP cependant! Je suppose que ce n'est pas un problème le convertir à JS.


1 commentaires

Parfait! Pour mes amis JS, il existe json.parse (Dirtyjson.replace (/ ([{,]) (\ s *) ([A-ZA-Z0-9 _ \ -] +?) \ S *: / g, '$ 1 "3 $":'))