您不能使用正则表达式从任意文本中提取 JSON。由于正则表达式通常是not powerful enough to validate JSON(除非您可以使用 PCRE),因此它们也无法匹配 - 如果可以,它们也可以验证 JSON。
但是,如果您知道 JSON 的顶级元素始终是对象或数组,则可以采用以下方法:
- 在字符串中找到第一个开头(
{ 或 [)和最后一个结尾(} 或 ])大括号。
- 尝试使用
JSON.parse() 解析该文本块(包括大括号)。如果成功,完成并返回解析结果。
- 使用前一个右大括号并尝试解析该字符串。如果成功,您将再次完成。
- 重复此操作,直到没有大括号或在当前开口大括号之前出现一个大括号。
- 在第 1 步中找到第一个左大括号。如果没有找到,则字符串不包含 JSON 对象/数组,您可以停止。
- 转到第 2 步。
这是一个提取 JSON 对象并返回对象及其位置的函数。如果你真的也需要顶级数组,那应该是扩展:
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(在 nodejs 环境中执行,但也应该在浏览器中运行):https://paste.aeum.net/show/81/