我有一个这样的字符串:
var s = '{ "foo": { "bar": { "baz": 5 } } } Some more content';
在JavaScript中是否有可靠的方法将字符串拆分为JSON和非JSON部分?该字符串始终以有效的JSON开头,但除此之外JSON可以包含任何内容,因此计算括号的技巧不会起作用。
我目前看到的最佳选择是使用json-lint模块获取错误的位置并在错误位置拆分。
还有其他想法吗?
答案 0 :(得分:2)
正如评论中所述,你真的应该考虑清理你正在使用的字符串,以便它只是真正的JSON。
尽管如此,如果你真的想要按照自己的方式继续前进,那么只需使用vanilla JavaScript就可以实现这一目标。如您所说,这假定字符串始终以“有效”JSON开头。
function splitMyJsonString(string) {
var jsonData = getValidJson(string);
return [
jsonData.json,
string.split('').slice(jsonData.errorIndex).join('')
];
function getValidJson(s) {
var newString = '';
for (var i = 0; i < s.length; i++) {
try {
return {json: JSON.parse(newString), errorIndex: i}
}
catch (e) {
newString += s.charAt(i);
}
}
return {json: null, errorIndex: 0}
}
}
从函数调用中返回的是一个数组,其中第一个索引是您解析的JSON作为对象,第二个索引是剩余的字符串(因为您要求拆分)。如果在字符串的开头没有找到有效的json,则会返回一个数组,其中第一个索引为null
。
var s = '{ "foo": { "bar": { "baz": 5 } } } Some more content';
console.log(splitMyJsonString(s)); // logs: [Object, " Some more content"]
// If no valid JSON is at the start of the string...
var z = 'Some more content';
console.log(splitMyJsonString(z)); // logs [null, "Some more content"]
首先,我们将整个字符串拆分为一个数组,以便稍后进行数组切片。然后我们从字符串的开头获取有效的JSON。我们这样做的方法是尝试一次解析一块,直到我们得到一个实际的传递(叹息)。一旦通过,或者我们不返回值。我在解释中留下了一些空白,但主要内容已被涵盖。
function splitMyJsonString(string) {
var jsonData = getValidJson(string);
return [
jsonData.json,
string.split('').slice(jsonData.errorIndex).join('')
];
function getValidJson(s) {
var newString = '';
for (var i = 0; i < s.length; i++) {
try {
return {
json: JSON.parse(newString),
errorIndex: i
}
} catch (e) {
newString += s.charAt(i);
}
}
return {
json: null,
errorIndex: 0
}
}
}
var s = '{ "foo": { "bar": { "baz": 5 } } } Some more content';
console.log(splitMyJsonString(s)); // logs: [Object, " Some more content"]
// If no valid JSON is at the start of the string...
var z = 'Some more content';
console.log(splitMyJsonString(z)); // logs [null, "Some more content"]
答案 1 :(得分:2)
使用与KevBot相同的方法,但可能消除了很多try {} catch(e) {}
:
var s = '{ "foo": { "bar": { "baz": 5 } } } Some mo}re }content';
var offset = s.length + 1;
while (offset > 0) {
offset = s.lastIndexOf('}', offset - 1);
var maybe_json = s.slice(0, offset + 1);
try {
var json = JSON.parse(maybe_json);
break;
} catch (e) {}
}
var rest = s.slice(offset + 1);
console.log(json); // { "foo": { "bar": { "baz": 5 } } }
console.log(rest); // " Some mo}re }content"