AJAX 调用正在返回包含 JSON 字符串的响应文本。我需要:
- 提取 JSON 字符串
- 修改它
- 然后重新插入它以更新原始字符串
我不太担心第 2 步和第 3 步,但我不知道如何执行第 1 步。我正在考虑使用正则表达式,但我不知道我的 JSON 可能有多级嵌套对象或数组。
AJAX 调用正在返回包含 JSON 字符串的响应文本。我需要:
我不太担心第 2 步和第 3 步,但我不知道如何执行第 1 步。我正在考虑使用正则表达式,但我不知道我的 JSON 可能有多级嵌套对象或数组。
您不能使用正则表达式从任意文本中提取 JSON。由于正则表达式通常不足以验证 JSON(除非您可以使用 PCRE),因此它们也无法匹配它 - 如果可以,它们也可以验证 JSON。
但是,如果您知道 JSON 的顶级元素始终是对象或数组,则可以采用以下方法:
{
或[
)和最后一个结束(}
或]
)大括号。JSON.parse()
。如果成功,则完成并返回解析结果。这是一个提取 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]));
演示(在 nodejs 环境中执行,但也应该在浏览器中工作):https ://paste.aeum.net/show/81/
对于其他正在寻找(就像我一样)从一般文本中提取 JSON 字符串(即使它们无效)的人,您可以查看这个 Gulp 插件https://www.npmjs.com/package/gulp -extract-json-like。它搜索所有看起来像 JSON 字符串一样格式化的字符串。
创建一个文件夹并安装软件包。
mkdir project && cd project
npm install gulp gulp-extract-json-like
创建一个文件./gulpfile.js
并将以下内容放入其中:
var gulp = require('gulp');
var extractJsonLike = require('gulp-extract-json-like');
gulp.task('default', function () {
return gulp.src('file.txt')
.pipe(extractJsonLike())
.pipe(gulp.dest('dist'));
});
创建一个名为的文件./file.txt
,其中包含您的文本并运行以下命令。
gulp
找到的 JSON 字符串将在./dist/file.txt
.
如果 JSON 作为 ajax 响应的一部分返回,为什么不使用浏览器的原生 JSON 解析(小心陷阱)?还是jQuery JSON 解析?
如果 JSON 完全与文本混淆,那真的是设计问题恕我直言 - 如果您可以更改它,我强烈建议您这样做(即返回单个 JSON 对象作为响应,文本作为属性物体)。
如果没有,那么使用 RegEx 将是一场绝对的噩梦。JSON 天生就非常灵活,确保准确解析不仅费时,而且浪费。我可能会在开始/结束时放置内容标记,并希望最好。但是您将对验证错误等持开放态度。