假设我有一个 node.js 应用程序,它以一种奇怪的格式接收输入:带有任意散布在其中的 JSON 的字符串,如下所示:
This is a string {"with":"json","in":"it"} followed by more text {"and":{"some":["more","json"]}} and more text
我对此输入文本有几个保证:
JSON 对象之间的文字文本位始终不包含花括号。
推入文本的顶级 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(使用前将#替换为@)