JSON teil aus string extracten?

3 Antworten

Genau hierfür gibt es:

https://docs.python.org/3/library/json.html

Wenn Du den String erst zerlegen mußt:

>>> s='JSON string be here equitation and more shit here'
>>> s.partition('equitation')
('JSON string be here ', 'equitation', ' and more shit here')

Kann man das trivial auch so machen und auch noch strippen etc. .

Und das heißt in letzter Konsequenz, sei s Dein string:

import json

data=json.loads(s.partition('equitation')[0])

und fertig wäre das ganze (ohen Fehlerbehandlugn versteht sich).


Erzesel  27.07.2024, 20:02

...wär zu schön, aber innerhab des "legitimen" Teils steckt leider auch schon ein:

{..., "equitation": 4590,...} damit würde der string bereits dort getrennt und nicht am letzten vorkommen . ganz so simpel ist es auch nicht.

Meine Variante alles zwischen der ersten"{" und der letzten"}" abzufischen ist auch nicht Narrensicher und verlässt sich darauf, dass alle Klammern dazwischen im Gleichgewicht sind.

Eine perfekte Lösung für dergleichen gibt's wahrscheinlich nicht...

0
KarlRanseierIII  27.07.2024, 20:55
@Erzesel

Beim angebenen Beispiel könnte man beim Seperator auch einfach ein Leerzeichen ergänzen.

Und klar könnte man auch nen re.split() o.ä. nehmen - aber um das zu beurteilen bräuchte man die Datenbasis.

Denn wenn alle Stricke reißen, müßte man einfach einen abgewandelten JSON-Decoder bauen, der den korrekten JSON-Teil aus dem String konsumiert und dann 10 grade sein lässt.

Aber da sind einfach zu viele wenn, aber und die Präzision der Problembeschreibung in der Frage lässt auch sehr zu wünschen übrig.

1
cleanercode  27.07.2024, 18:41

Darauf bin ich auch reingefallen, seine Struktur endet allerdings bei

equitation

und es ist insgesamt ein String.

2

Da Dein Strig kein legitimes JSON ist, steigt der Parser natürlich mit einer Fehlermeldung bezüglich "Extradata" aus.

'{...} equitation' gehört hier nicht mehr zu json! und der Parser weiß nicht was er damit anfangen soll.

ich würde es (in diesem Fall) einfach mit der "Brechstange" also plumber Stringakrobatik lösen. Dafür bietet sich ei kleine RegEx an:

"\{.*\}"

  • beginn des Suchstrings mit {
  • belibige Zeichen .* (* ist gefräßig, also frist er bis zum letzten Matchcharacter im definierten Pattern)
  • ende des Suchstrings mit }

Butter bei die Fische:

badJSON = '{"tarahumar": 2003, "fustier": ["grugrus", "swadeshi", "trillionize", "unpoeticized", "pseudoperipteral", "drakefly", "towaway"], "obtainers": "henchman", "stranglingly": "podded", "quatorzain": 2828.6, "funnel": "coscoroba", "motherly": 1070, "equitation": 4590, "nongraphitic": ["overhumane", "natica", "raspberries", "digestedly", "choraleon", "hypoleucocytosis"], "puckerier": "illegitimated"} equitation'
matches = re.findall("\{.*\}", badJSON)  #extrahiere  alles  von der   ersten   bis zur letzten geschweiften Klammer
pureJSONString = ''.join(matches) #mache  aus der Liste  von Treffern (sollte  nur  einer  sein) einen String
print(pureJSONString)


#Mal probieren obs  der  JSONparser  schluckt . jetz  sollte   keine Fehlermeldung kommen
MyObject = json.loads(pureJSONString)
print(MyObject) 

Die Lösung per brutaler Stringverarbeitung ist nicht schön. ...aber ainfach zu handhaben😤😏.


cleanercode  27.07.2024, 18:50

Ich mache mir Mühe, importiere kein json-Modul, kein json.loads() und was machst du?! Eiskalt die Lösung präsentieren! :-D

1
Erzesel  27.07.2024, 19:28
@cleanercode

das jsonmodul habe ich auch nur zum testen verwendet.

ich bin eigentlich kein "Pythoner" (oder wie die sich nennen) .

Im Prinzip hilft bei irgendwelchen kaputten Zeug auch in anderen Sprachen der Weg über Stringverarbeitung.

in Powershell hätte ich noch weniger Zirkus veranstaltet:

$badJSON = '{"tarahumar": 2003, "fustier": ["grugrus", "swadeshi", "trillionize", "unpoeticized", "pseudoperipteral", "drakefly", "towaway"], "obtainers": "henchman", "stranglingly": "podded", "quatorzain": 2828.6, "funnel": "coscoroba", "motherly": 1070, "equitation": 4590, "nongraphitic": ["overhumane", "natica", "raspberries", "digestedly", "choraleon", "hypoleucocytosis"], "puckerier": "illegitimated"} equitation'
[Regex]::Matches($badJSON,'\{.*\}').Value|ConvertFrom-Json|fl *
1

====================================

Ich kann nicht lesen, daher eine Korrektur :)

====================================

Mit RegEx kannst du nach equitation suchen und es durch "}" ersetzen.

Dies geschieht so:

import re

# Suche bitte nach equitation und zwar nur,
# wenn unmittelbar davor das Zeichen } steht.
regex = r"[}](equitation)"

# Es wird später entfernt und die leere Stelle muss
# selbstverständlich wieder befüllt werden
substitution = "}"

# Selbsterklärend
new_dict: dict = ""

# Deine Rohdaten
raw_data = """{
    "tarahumar": 2003,
    "fustier": [
        "grugrus",
        "swadeshi",
        "trillionize",
        "unpoeticized",
        "pseudoperipteral",
        "drakefly",
        "towaway"
    ],
    "obtainers": "henchman",
    "stranglingly": "podded",
    "quatorzain": 2828.6,
    "funnel": "coscoroba",
    "motherly": 1070,
    "equitation": 4590,
    "nongraphitic": [
        "overhumane",
        "natica",
        "raspberries",
        "digestedly",
        "choraleon",
        "hypoleucocytosis"
    ],
    "puckerier": "illegitimated"
}equitation"""


result = re.sub(regex, substitution, raw_data, 0, re.MULTILINE)

Wurde equitation gefunden, wird das Ergebnis in "result" gespeichert.

Vorher bitte prüfen, ob result tatsächlich Daten hat und die Daten zur Verfügung stehen.

if result:
    new_data = result
    print(new_data)

"new_data" hat nun eine saubere JSON-Struktur (da Dictionary) und du kannst die Werte auslesen - ABER das überlasse ich dir :-)

Ausgabe:

{
    "tarahumar": 2003,
    "fustier": [
        "grugrus",
        "swadeshi",
        "trillionize",
        "unpoeticized",
        "pseudoperipteral",
        "drakefly",
        "towaway"
    ],
    "obtainers": "henchman",
    "stranglingly": "podded",
    "quatorzain": 2828.6,
    "funnel": "coscoroba",
    "motherly": 1070,
    "equitation": 4590,
    "nongraphitic": [
        "overhumane",
        "natica",
        "raspberries",
        "digestedly",
        "choraleon",
        "hypoleucocytosis"
    ],
    "puckerier": "illegitimated"
}