it-swarm.com.de

Regex für die Analyse eines einzelnen Schlüssels: Werte aus JSON in Javascript

Ich versuche zu sehen, ob es möglich ist, einzelne _ keys aus einer _ _ JSON-Zeichenfolge in Javascript nachzuschlagen, und es ist Value mit Regex zurückzugeben. So etwas wie das Erstellen eines JSON-Suchwerkzeugs.

Stellen Sie sich folgendes JSON vor

"{
    "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"
                }
            ]
        }
    ]
}"

Ich möchte in der Lage sein, die JSON-Zeichenfolge zu durchsuchen und nur einzelne Eigenschaften herauszuziehen.

nehmen wir an, es ist bereits ein function, es würde ungefähr so ​​aussehen.

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+"\":","");    
}

Es würde die Teilzeichenfolge von Value für Key zurückgeben.

z.B.

getPropFromJSON("Comments")

> "[
    { 
        "User":"Fairy God Mother",
        "Comment": "Ha, can't say I didn't see it coming"
    }
]"

Wenn Sie sich fragen, warum ich dies tun möchte, anstatt JSON.parse() zu verwenden, baue ich einen JSON-Dokumentenspeicher um localStorage. Da localStorage nur Schlüssel/Wert-Paare unterstützt, speichere ich eine JSON-Zeichenfolge des gesamten Document in einem eindeutigen Key. Ich möchte in der Lage sein, eine Abfrage für die Dokumente auszuführen, im Idealfall ohne den Aufwand von JSON.parsing() der gesamten Collection von Documents, um dann über die Keys/verschachtelte Keys-Datei eine Übereinstimmung zu finden.

Ich bin nicht der Beste bei regex, also weiß ich nicht, wie das geht, oder ob es überhaupt mit regex möglich ist. Dies ist nur ein Experiment, um herauszufinden, ob dies möglich ist. Alle anderen Ideen als Lösung wären willkommen. 

12
AshHeskes

Ich würde Sie dringend davon abhalten, dies zu tun. JSON ist keine reguläre Sprache, wie hier eindeutig angegeben: https://cstheory.stackexchange.com/questions/3987/is-json-a-regular-language

Um aus dem obigen Beitrag zu zitieren: 

Stellen Sie sich beispielsweise ein Array von Arrays von Arrays vor:

[ [ [ 1, 2], [2, 3] ] , [ [ 3, 4], [ 4, 5] ] ] 

Natürlich können Sie das nicht mit echten regulären Ausdrücken analysieren.

Ich empfehle, Ihre JSON in ein Objekt (JSON.parse) zu konvertieren und eine Suchfunktion zu implementieren, um die Struktur zu durchlaufen.

Abgesehen davon können Sie sich die Methoden von Douglas Crockford json2.js parse ansehen. Möglicherweise können Sie mit einer geänderten Version die JSON-Zeichenfolge durchsuchen und nur das gewünschte Objekt zurückgeben, ohne die gesamte Struktur in ein Objekt zu konvertieren. Dies ist nur nützlich, wenn Sie niemals andere Daten von Ihrem JSON abrufen. Wenn Sie dies tun, könnten Sie das Ganze auch gleich umgestellt haben. 

EDIT 

Um noch weiter zu zeigen, wie Regex zusammenbricht, hier eine Regex, die versucht, JSON zu analysieren

Wenn Sie es in http://regexpal.com/ mit "Dot Matches All" einchecken, ist das Häkchen gesetzt. Sie werden feststellen, dass es einige Elemente gut passen kann:

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"

Sobald Sie jedoch nach höheren Strukturen wie "Posts" fragen, die verschachtelte Arrays enthalten, werden Sie feststellen, dass Sie die Struktur nicht korrekt zurückgeben können, da der reguläre Ausdruck keinen Kontext hat, dessen "]" das angegebene Ende von ist Struktur. 

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"
          }
      ]
24
Brandon Boone

Stringify zuerst das JSON-Objekt. Dann müssen Sie den Anfang und die Länge der übereinstimmenden Teilzeichenfolgen speichern. Zum Beispiel:

"matched".search("ch") // yields 3

Für einen JSON-String funktioniert dies genau gleich (sofern Sie nicht explizit nach Kommas und geschweiften Klammern suchen. In diesem Fall empfehle ich eine vorherige Transformation Ihres JSON-Objekts, bevor Sie einen Regex ausführen (d. H. Think:, {,}).

Als Nächstes müssen Sie das JSON-Objekt rekonstruieren. Der von mir erstellte Algorithmus tut dies, indem er die JSON-Syntax erkennt, indem er rekursiv vom Übereinstimmungsindex zurückspringt. Zum Beispiel könnte der Pseudo-Code folgendermaßen aussehen:

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

Mit diesen Informationen ist es möglich, Regex zum Filtern eines JSON-Objekts zu verwenden, um den Schlüssel, den Wert und die übergeordnete Objektkette zurückzugeben.

Die Bibliothek und den Code, den ich verfasst habe, finden Sie unter http://json.spiritway.co/

0
mikewhit