2017-01-24 4 views
0

Das Folgende ist ein Beispiel json Zeichenfolge zu analysieren, dieautomatisch einfügen Backslash JSON-String mit doppelten Anführungszeichen

parsed- sein muss
'{ 
"name":"bla", 
"quote":"bla bla "blah blah" bla", 
"occupation":"blabla" 
}' 

ich automatisch einfügen müssen \\ die beiden Zitate entkommen zu analysieren. Ich folgte this. Aber das Problem ist, es teilt die Zeichenfolge durch :, weil es annimmt, dass die JSON-Zeichenfolge nur einen Schlüsselwert hat. Außerdem kann ich auch nicht durch , teilen, weil der quote Abschnitt , in seinem Text enthalten kann. zum Beispiel "quote":"bla bla, "blah blah" bla". Im Gegensatz zu dieser Antwort brauche ich eine robustere Lösung. Wie kann ich das machen? Ich kann mir keine Änderung dieser Antwort vorstellen, das wird in meinem Fall perfekt funktionieren.

+1

Dies kann nicht in einer allgemeinen, zuverlässigen Art und Weise gelöst werden. Reparieren Sie die Anwendung, die das falsche JSON erzeugt, an erster Stelle, damit ein gültiges JSON erstellt wird. – Barmar

+0

Der ganze Grund, warum JSON eingebettete Anführungszeichen benötigt, um es zu maskieren, liegt daran, dass alles andere mehrdeutig ist. Wenn es automatisch behoben werden könnte, wären die Standard-JSON-Parser in der Lage, dies selbst zu tun. – Barmar

+0

Wird die Datei wie in Ihrem Beispiel neu eingefügt? – TemporalWolf

Antwort

2

Dies ist definitiv eine fehlerhafte JSON und es gibt keine robuste Möglichkeit, es zu analysieren, die alle möglichen Fälle abdeckt.

Wenn Sie wissen, dass dies die Struktur jeder Zeile ist, können Sie versuchen, indem Sie in einer mehr verschachtelten Weise splitten, wie mit ":", aber das ist nicht zuverlässig. Eine Alternative wäre es, eine Regex zu verwenden, aber es ist komplizierter und es könnte unter den gleichen Problemen leiden.

Die beste Lösung wäre, zu der Person zu gehen, die diesen JSON erstellt hat, ihn ins Gesicht schlagen und ihn bitten, die Datei neu zu kodieren, aber ich kann mir vorstellen, dass dies nicht möglich ist.

+0

Ja, du hast Recht, das ist nicht möglich. weil dieser 'Zitat'-Schlüssel tatsächlich Millionen von Tweets ist. Leute benutzen häufig Zitat innerhalb ihrer Tweets –

+0

Und wie erhalten Sie diese Daten zurück? Ich glaube nicht, dass twitter API nicht richtig codiert. – Chobeat

+0

Ich verwende einen Crawler. Die Ausgabe des Crawlers ist wie folgt '{"name": "bla", "Zitat": "bla bla" bla bla "bla", "beruf": "blabla"}' Aber wenn ich dies lese in meinem Python-Code bekomme ich das - '{"name": "bla", "zitat": "bla bla" bla bla "bla", "beruf": "blabla"}'. Deshalb, wenn ich versuchte, "\" durch "\\" zu ersetzen, funktioniert es nicht. Das wäre das ganze Problem gelöst worden. –

0

Gegeben zwei (ziemlich groß) Räumlichkeiten, kann es noch analysiert werden:

  1. {, }, & : sind keine gültigen Werte für eines der Felder
  2. Jeder Eintrag {} besteht aus 3 Teilen

2 könnte entfernt werden, wenn Sie das Parsen von Schlüssel/Wert-Paaren verallgemeinern, wenn die Anzahl variiert.

1 kann auch leicht entspannt sein kann, wenn Sie sagen, dass : kann nur in den Wertfeldern erscheinen (in beliebiger Menge).This would be mutually exclusive to #2, however.

Die Regex:

{\"([^\"]*)\":\"([^:\n\r]*)\",?\"([^\"]*)\":\"([^:\n\r]*)\",?\"([^\"]*)\":\"([^:\n\r]*)\",?} 

oder als Ausgangs string:

r'{"([^"]*)":"([^:\n\r]*)",?"([^"]*)":"([^:\n\r]*)",?"([^"]*)":"([^:\n\r]*)",?}' 

regex101

HINWEIS: Dieser Griff keine Leerzeichen in den JSON Teile, aber das kann bei Bedarf hinzugefügt werden, es ist schon ziemlich lang/

Verbrauch:

pattern = r'{"([^"]*)":"([^:\n\r]*)",?"([^"]*)":"([^:\n\r]*)",?"([^"]*)":"([^:\n\r]*)",?}' 
matches = re.findall(pattern, input) 
for match in matches: 
    result = {match[0]: match[1], match[2]: match[3], match[4]: match[5]} 
    # Do something with each result 

Im Einsatz:

>>> pattern = '{\"([^\"]*)\":\"([^:\n\r]*)\",?\"([^\"]*)\":\"([^:\n\r]*)\",?\"([^\"]*)\":\"([^:\n\r]*)\",?}' 
>>> matches = re.findall(pattern, input) 
>>> for match in matches: 
    result = {match[0]: match[1], match[2]: match[3], match[4]: match[5]} 
>>> result 
{'quote': 'bla bla "blah blah" bla', 'name': 'bla', 'occupation': 'blabla'} 

Ein weiteres Beispiel:

>>> input = """{"name":"b"testst,s'''""'''''''t""e,"la","quote":"bla bla "blah b,lah" bla","occupation":"bl,,,abla"}""" 
>>> matches = re.findall(pattern, input) 
>>> for match in matches: 
     result = {match[0]: match[1], match[2]: match[3], match[4]: match[5]} 
>>> result 
{'quote': 'bla bla "blah b,lah" bla', 'name': 'b"testst,s\'\'\'""\'\'\'\'\'\'\'t""e,"la', 'occupation': 'bl,,,abla'} 
Verwandte Themen