Sie können keine Regex verwenden, um JSON aus einem beliebigen Text zu extrahieren. Da Regexes normalerweise not powerful enough to validate JSON sind (es sei denn, Sie können PCRE verwenden), können sie auch nicht übereinstimmen - wenn sie könnten, könnten sie auch JSON validieren.
Wenn Sie jedoch wissen, dass die Top-Level-Element Ihrer JSON ist immer ein Objekt oder ein Array, können Sie durch den folgenden Ansatz gehen:
- Finden Sie die erste Öffnung (
{
oder [
) und letzten Schließen (}
oder ]
) Klammer in Ihrer Zeichenfolge.
- Versuchen Sie, diesen Textblock (einschließlich der geschweiften Klammern) mit
JSON.parse()
zu analysieren. Wenn es erfolgreich war, beenden Sie das geparste Ergebnis und geben Sie es zurück.
- Nehmen Sie die vorherige schließende Klammer und versuchen Sie, diese Zeichenfolge zu analysieren. Wenn es gelingt, sind Sie wieder fertig.
- Wiederholen Sie dies, bis Sie keine Klammer oder eine, die vor der aktuellen öffnenden Klammer kommt.
- Suchen Sie die erste öffnende Klammer nach der aus Schritt 1. Wenn Sie keine gefunden haben, enthielt die Zeichenfolge kein JSON-Objekt/Array und Sie können anhalten.
- Go 2.
Hier ist eine Funktion zum Schritt, der ein Objekt JSON extrahiert und gibt das Objekt und seine Position. Wenn Sie wirklich Top-Level-Arrays benötigen auch, sollte es zu erweitern sein:
function extractJSON(str) {
var firstOpen, firstClose, candidate;
firstOpen = str.indexOf('{', firstOpen + 1);
do {
firstClose = str.lastIndexOf('}');
console.log('firstOpen: ' + firstOpen, 'firstClose: ' + firstClose);
if(firstClose <= firstOpen) {
return null;
}
do {
candidate = str.substring(firstOpen, firstClose + 1);
console.log('candidate: ' + candidate);
try {
var res = JSON.parse(candidate);
console.log('...found');
return [res, firstOpen, firstClose + 1];
}
catch(e) {
console.log('...failed');
}
firstClose = str.substr(0, firstClose).lastIndexOf('}');
} while(firstClose > firstOpen);
firstOpen = str.indexOf('{', firstOpen + 1);
} while(firstOpen != -1);
}
var obj = {'foo': 'bar', xxx: '} me[ow]'};
var str = 'blah blah { not {json but here is json: ' + JSON.stringify(obj) + ' and here we have stuff that is } really } not ] json }} at all';
var result = extractJSON(str);
console.log('extracted object:', result[0]);
console.log('expected object :', obj);
console.log('did it work ?', JSON.stringify(result[0]) == JSON.stringify(obj) ? 'yes!' : 'no');
console.log('surrounding str :', str.substr(0, result[1]) + '<JSON>' + str.substr(result[2]));
Demo (in der NodeJS Umgebung ausgeführt, sollte aber in einem Browser arbeiten, auch): https://paste.aeum.net/show/81/
Sie sind nicht neu hier. Was hast du probiert? Wie sieht deine Antwort aus? –
Auch RegEx ist wahrscheinlich nicht das richtige Werkzeug für den Job. –
@Truth meine einzige Problemumgehung ist bisher, Markierungen in den Antworttext einzufügen, um den Anfang und das Ende der JSON-Zeichenfolge anzuzeigen. Nichts, worauf man stolz sein könnte oder das würde die Antwort leiten. – Christophe