从文本中提取JSON

Chr*_*phe 11 javascript regex json

AJAX调用返回包含JSON字符串的响应文本.我需要:

  1. 提取JSON字符串
  2. 修改它
  3. 然后重新插入它以更新原始字符串

我并不太担心第2步和第3步,但我无法弄清楚如何执行第1步.我正在考虑使用正则表达式,但我不知道我的JSON如何与嵌套对象具有多个级别或数组.

Thi*_*ter 13

您不能使用正则表达式从任意文本中提取JSON.由于正则表达式通常不足以验证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]));
Run Code Online (Sandbox Code Playgroud)

演示(在nodejs环境中执行,但也应在浏览器中运行):https://paste.aeum.net/show/81/