如何解析Node中的非结构化JSON文件?

时间:2017-03-20 18:39:03

标签: json node.js

我必须解析一个JSON文件,该文件包含许多对象但文件没有结构。它看起来像这样:

{"obj1": "john"}
{"obj2": "sally"}
{"obj3": "veronica"}

每个对象都在它上面,没有容器。因此,当我打开文件并尝试迭代它时,我收到错误Unexpected token { in JSON

除了将对象包装在一个数组中,然后手动浏览整个文件以添加逗号之外,我该如何解析它?

2 个答案:

答案 0 :(得分:2)

如果它实际上是每行一个对象,那么获取字符串,将其分成行,并且每行JSON.parse相当简单:

const str =
  '{"obj1": "john"}\n' +
  '{"obj2": "sally"}\n' +
  '{"obj3": "veronica"}';

const array = str.split(/[\r\n]+/)
                 .map(entry => JSON.parse(entry));

console.log(array);

...但是假设它确实是每行一个对象。

如果您正在阅读该文件,则不必像上面那样以一个字符串开头;仅read line by lineKevin B points out

(由于您使用的是Node,我很高兴使用上面的ES2015 +功能......)

答案 1 :(得分:1)

如果你假设输入文件的每一行都是完整的,独立的JSON,那么分裂成行然后解析每个策略都可以。

但即使数据不限于一行,也不会全部丢失。您可以尝试解析文件。它不是超高效的,但除了非常大的文件,你可能永远不会知道它们之间的区别:

function incrementallyParseJSON(filepath) {
    var lines = fs.readFileSync(filepath)
                  .toString()
                  .split(/\n/g);
    var result = [];
    var [start, stop] = [0, 1];
    while (stop <= lines.length) {
        try { 
            var part = JSON.parse(lines.slice(start, stop).join('\n'));
            result.push(part);
            [start, stop] = [stop, stop+1]; 
        } catch (e) {
            stop += 1;
        }
    }
    return result;
}

因此,如果您的文件是:

{"obj1": "john"}
{"obj2": "sally",
 "more": "other"}
{"obj3": "veronica"}
"something"
12

结果将是:

[ { obj1: 'john' },
  { obj2: 'sally', more: 'other' },
  { obj3: 'veronica' },
  'something',
  12 ]

示例:

&#13;
&#13;
function incrementallyParseJSON(str) {
    var lines = str.split(/\n/g);
    var result = [];
    var [start, stop] = [0, 1];
    while (stop <= lines.length) {
        try { 
            var part = JSON.parse(lines.slice(start, stop).join('\n'));
            result.push(part);
            [start, stop] = [stop, stop+1]; 
        } catch (e) {
            stop += 1;
        }
    }
    return result;
}
var str =
  '{"obj1": "john"}\n' +
  '{"obj2": "sally",\n' +
  ' "more": "other"}\n' +
  '{"obj3": "veronica"}\n' +
  '"something"\n' +
  '12';

console.log(incrementallyParseJSON(str));
&#13;
&#13;
&#13;