J'essaie de voir s'il est possible de rechercher une variable keys
dans une chaîne JSON
en Javascript et de la renvoyer par Value
avec Regex
. Un peu comme construire un outil de recherche JSON
.
Imaginez le JSON suivant
"{
"Name": "Humpty",
"Age": "18",
"Siblings" : ["Dracula", "Snow White", "Merlin"],
"Posts": [
{
"Title": "How I fell",
"Comments": [
{
"User":"Fairy God Mother",
"Comment": "Ha, can't say I didn't see it coming"
}
]
}
]
}"
Je souhaite pouvoir effectuer une recherche dans la chaîne JSON
et extraire uniquement les propriétés individuelles.
supposons que c'est déjà une function
, cela ressemblerait à quelque chose.
function getPropFromJSON(prop, JSONString){
// Obviously this regex will only match Keys that have
// String Values.
var exp = new RegExp("\""+prop+"\"\:[^\,\}]*");
return JSONString.match(exp)[0].replace("\""+prop+"\":","");
}
Il renverrait la sous-chaîne de la Value
pour la Key
.
par exemple.
getPropFromJSON("Comments")
> "[
{
"User":"Fairy God Mother",
"Comment": "Ha, can't say I didn't see it coming"
}
]"
Si vous vous demandez pourquoi je veux faire cela au lieu d'utiliser JSON.parse()
, je construis un magasin de documents JSON autour de localStorage
. localStorage
ne prend en charge que les paires clé/valeur, je stocke donc une chaîne JSON
de la totalité de Document
dans une Key
unique. Je veux pouvoir exécuter une requête sur les documents, idéalement sans la surcharge de JSON.parsing()
, de la Collection
entière de Documents
puis de la récursion sur la Keys
/nested Keys
pour trouver une correspondance.
Je ne suis pas le meilleur à regex
donc je ne sais pas comment faire cela, ou si c'est même possible avec regex
seul. Ce n'est qu'une expérience pour savoir si c'est possible. Toute autre solution pourrait être appréciée.
Je vous déconseillerais fortement de le faire. Le langage JSON n’est pas un langage courant comme indiqué clairement ici: https://cstheory.stackexchange.com/questions/3987/is-json-a-regular-language
Pour citer le post ci-dessus:
Par exemple, considérons un tableau de tableaux de tableaux:
[ [ [ 1, 2], [2, 3] ] , [ [ 3, 4], [ 4, 5] ] ]
Il est clair que vous ne pouvez pas analyser cela avec de vraies expressions régulières.
Je vous recommande de convertir votre JSON en objet (JSON.parse) et d'implémenter une fonction de recherche pour parcourir la structure.
En dehors de cela, vous pouvez jeter un coup d'oeil aux tripes de la méthode json2.js parse de Douglas Crockford. Peut-être qu'une version modifiée vous permettrait de rechercher dans la chaîne JSON et de simplement renvoyer l'objet que vous recherchiez sans convertir l'intégralité de la structure en objet. Cela n'est utile que si vous ne récupérez jamais d'autres données à partir de votre JSON. Si vous le faites, vous pourriez aussi bien avoir tout converti pour commencer.
EDIT
Juste pour montrer comment Regex se décompose, voici une expression rationnelle qui tente d'analyser JSON
Si vous le branchez dans http://regexpal.com/ avec la case "Tous les points sont cochés". Vous constaterez qu'il peut correspondre à certains éléments comme:
Regex_
"Comments"[ :]+((?=\[)\[[^]]*\]|(?=\{)\{[^\}]*\}|\"[^"]*\")
JSON Matched
"Comments": [ { "User":"Fairy God Mother", "Comment": "Ha, can't say I didn't see it coming" } ]
Regex_
"Name"[ :]+((?=\[)\[[^]]*\]|(?=\{)\{[^\}]*\}|\"[^"]*\")
JSON Matched
"Name": "Humpty"
Cependant, dès que vous commencez à interroger les structures supérieures telles que "Posts", qui contient des tableaux imbriqués, vous constaterez que vous ne pouvez pas renvoyer correctement la structure car l'expression rationnelle n'a pas de contexte dans lequel "]" est la fin désignée de l'élément. structure.
Regex_
"Posts"[ :]+((?=\[)\[[^]]*\]|(?=\{)\{[^\}]*\}|\"[^"]*\")
JSON Matched
"Posts": [ { "Title": "How I fell", "Comments": [ { "User":"Fairy God Mother", "Comment": "Ha, can't say I didn't see it coming" } ]
Tout d'abord, stringify l'objet JSON. Ensuite, vous devez stocker les débuts et les longueurs des sous-chaînes correspondantes. Par exemple:
"matched".search("ch") // yields 3
Pour une chaîne JSON, cela fonctionne exactement de la même manière (à moins que vous ne recherchiez explicitement des virgules et des accolades, auquel cas je recommanderais une transformation préalable de votre objet JSON avant d'effectuer une expression régulière (c'est-à-dire think:, {,}).
Ensuite, vous devez reconstruire l'objet JSON. L'algorithme que j'ai créé le fait en détectant la syntaxe JSON en remontant récursivement de l'index de correspondance. Par exemple, le pseudo-code pourrait ressembler à ceci:
find the next key preceding the match index, call this theKey
then find the number of all occurrences of this key preceding theKey, call this theNumber
using the number of occurrences of all keys with same name as theKey up to position of theKey, traverse the object until keys named theKey has been discovered theNumber times
return this object called parentChain
Avec ces informations, il est possible d'utiliser regex pour filtrer un objet JSON afin de renvoyer la clé, la valeur et la chaîne d'objet parent.
Vous pouvez voir la bibliothèque et le code que j'ai créés à http://json.spiritway.co/