将字符串拆分为JSON和非JSON部分

时间:2016-05-23 19:30:00

标签: javascript json node.js split

我有一个这样的字符串:

var s = '{ "foo": { "bar": { "baz": 5 } } } Some more content';

在JavaScript中是否有可靠的方法将字符串拆分为JSON和非JSON部分?该字符串始终以有效的JSON开头,但除此之外JSON可以包含任何内容,因此计算括号的技巧不会起作用。

我目前看到的最佳选择是使用json-lint模块获取错误的位置并在错误位置拆分。

还有其他想法吗?

2 个答案:

答案 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"