update
This commit is contained in:
@@ -8,14 +8,25 @@ _FENCE = re.compile(r"```(?:json)?\s*(.*?)```", re.DOTALL)
|
||||
|
||||
|
||||
def parse(text: str):
|
||||
"""→ Objekt oder None. Nie werfen — der Aufrufer entscheidet über Retry."""
|
||||
"""→ Objekt oder None. Nie werfen — der Aufrufer entscheidet über Retry.
|
||||
Jeden Code-Fence UND den Gesamttext durchprobieren; erster Treffer gewinnt.
|
||||
(Nur den ersten Fence zu nehmen verlor JSON, das nach einem Prosa-Beispiel-
|
||||
Fence stand.)"""
|
||||
if not text:
|
||||
return None
|
||||
for kandidat in [m.group(1) for m in _FENCE.finditer(text)] + [text]:
|
||||
daten = _ein_kandidat(kandidat.strip())
|
||||
if daten is not None:
|
||||
return daten
|
||||
return None
|
||||
|
||||
|
||||
def _ein_kandidat(text: str):
|
||||
"""Erstes vollständiges JSON-Objekt/-Array in `text` (Klammer-Balance) oder
|
||||
None. Das FRÜHESTE Klammerzeichen entscheidet — sonst gewinnt ein {…} im
|
||||
Array-Inneren."""
|
||||
if not text:
|
||||
return None
|
||||
m = _FENCE.search(text)
|
||||
if m:
|
||||
text = m.group(1)
|
||||
text = text.strip()
|
||||
# Das FRÜHESTE Klammerzeichen entscheidet: sonst gewinnt ein {…} im Array-Inneren.
|
||||
erste = sorted((("{", "}"), ("[", "]")),
|
||||
key=lambda p: text.find(p[0]) if p[0] in text else len(text))
|
||||
for start_ch, end_ch in erste:
|
||||
|
||||
Reference in New Issue
Block a user