如何解析不可预测地散布到字符串中的 JSON?

2024-04-30

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

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

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

  1. JSON 对象之间的文字文本位始终不包含花括号。

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

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

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

到目前为止我已经写了一个简单的解决方案 https://hastebin.com/igugugotah.js它只是计算花括号的数量来决定 JSON 的开始和停止位置。但如果 JSON 包含带大括号的字符串,则此方法不起作用{"like":"this one } right here"}。我可以尝试通过执行类似的引用计数数学来解决这个问题,但随后我还必须考虑转义的引用。那时我感觉自己重做了太多的事情JSON.parse的工作。有没有更好的方法来解决这个问题?


您可以检查 JSON.parse 是否抛出错误来确定该块是否是有效的 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;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何解析不可预测地散布到字符串中的 JSON? 的相关文章

随机推荐