Non è possibile utilizzare un'espressione regolare per estrarre JSON da un testo arbitrario. Dal momento che le espressioni regolari sono in genere not powerful enough to validate JSON (a meno che non sia possibile utilizzare PCRE), non possono eguagliarlo: se lo fossero, potrebbero anche convalidare JSON.
Tuttavia, se si sa che l'elemento di livello superiore del vostro JSON è sempre un oggetto o un array, si può andare dalla seguente approccio:
- Trova la prima apertura (
{
o [
) e l'ultimo chiusura (}
o ]
) parentesi graffa nella stringa.
- Prova ad analizzare quel blocco di testo (incluse le parentesi) utilizzando
JSON.parse()
. Se ha avuto successo, completa e restituisce il risultato analizzato.
- Prendere la parentesi graffa precedente e provare l'analisi di quella stringa. Se ha successo, hai finito di nuovo.
- Ripetere fino a quando non si ottiene alcun rinforzo o uno che viene prima del rinforzo di apertura corrente.
- Trova la prima parentesi aperta dopo quella del passaggio 1. Se non la trovi, la stringa non contiene un oggetto/array JSON e puoi fermarti.
- Andare al punto 2.
Ecco una funzione che estrae un oggetto JSON e restituisce l'oggetto e la sua posizione. Se si ha realmente bisogno array di alto livello, anche, che dovrebbe essere di estendere:
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 (eseguito in ambiente nodejs, ma dovrebbe funzionare in un browser, anche): https://paste.aeum.net/show/81/
Non sei nuovo qui. Che cosa hai provato? Come appare la tua risposta? –
Inoltre, RegEx probabilmente non è lo strumento corretto per il lavoro. –
@Truth la mia unica soluzione finora è includere gli indicatori nel testo della risposta per mostrare l'inizio e la fine della stringa JSON. Niente di cui essere orgogliosi o che avrebbe guidato la risposta. – Christophe