javascript - 如何将不可预测的 JSON 解析成字符串?

标签 javascript node.js json

假设我有一个 node.js 应用程序,它以一种奇怪的格式接收输入:带有 JSON 的字符串任意散布到其中,如下所示:

这是一个字符串 {"with":"json","in":"it"} 后跟更多文本 {"and":{"some":["more","json"] }} 和更多文本

我对这个输入文本有几个保证:

  1. JSON 对象之间的文字位总是没有大括号。

  2. 插入文本的顶级 JSON 对象始终是对象字面量,而不是数组。

我的目标是将其拆分为一个数组,保留文字文本并解析出 JSON,如下所示:

[
    "This is a string ",
    {"with":"json","in":"it"},
    " followed by more text ",
    {"and":{"some":["more","json"]}},
    " and more text"
]

到目前为止,我已经写了一个 naive solution它只计算花括号来决定 JSON 从哪里开始和停止。但是,如果 JSON 中包含带有花括号的字符串 {"like":"this one } right here"},这将不起作用。我可以尝试通过做类似的引用计数数学来解决这个问题,但是我还必须考虑转义引号。在那一点上,我感觉我正在重做太多 JSON.parse 的工作。有没有更好的方法来解决这个问题?

最佳答案

您可以检查 JSON.parse 是否抛出错误以确定该 block 是否是有效的 JSON 对象。如果它抛出一个错误,那么未引用的 } 是不平衡的:

const tests = [
  '{"just":"json }}{}{}{{[]}}}}","x":[1,2,3]}',
  'Just a string',
  'This string has a tricky case: {"like":"this one } right here"}',
  'This string {} has a tiny JSON object in it.',
  '.{}.',
  'This is a string {"with":"json","in":"it"} followed by more text {"and":{"some":["more","json"]}} and more text',
];

tests.forEach( test => console.log( parse_json_interleaved_string( test ) ) );

function parse_json_interleaved_string ( str ) {
  const chunks = [ ];
  let last_json_end_index = -1;
  let json_index = str.indexOf( '{', last_json_end_index + 1 );
  for ( ; json_index !== -1; json_index = str.indexOf( '{', last_json_end_index + 1 ) ) {

    // Push the plain string before the JSON
    if ( json_index !== last_json_end_index + 1 )
        chunks.push( str.substring( last_json_end_index, json_index ) );

    let json_end_index = str.indexOf( '}', json_index + 1 );

    // Find the end of the JSON
    while ( true ) {
       try { 
         JSON.parse( str.substring( json_index, json_end_index + 1 ) );
         break;
       } catch ( e ) {
         json_end_index = str.indexOf( '}', json_end_index + 1 );
         if ( json_end_index === -1 )
           throw new Error( 'Unterminated JSON object in string' );
       }
    }

    // Push JSON
    chunks.push( str.substring( json_index, json_end_index + 1 ) );
    last_json_end_index = json_end_index + 1;
  }

  // Push final plain string if any
  if ( last_json_end_index === - 1 )
    chunks.push( str );
  else if ( str.length !== last_json_end_index )
    chunks.push( str.substr( last_json_end_index ) );

  return chunks;
}

关于javascript - 如何将不可预测的 JSON 解析成字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54608178/

相关文章:

javascript - 无法设置所选属性。未指定的错误。 knockout

javascript - 无法在 React 组件中导入 ES6 模块

node.js - 在模型中创建模型

c# - 创建包含其他对象数组 [] 的对象

javascript - 访问以下 JSON 中的值

javascript - 如何将事件从 Polymer 的 rootScope 向下广播到元素?

javascript - JavaScript 中的空白字符串是真值还是假值?

javascript - Node.js 修改来自不同文件的变量

javascript - 将数组与数组的数组组合

python - 将 np 数组的字典保存到 json 文件