JSON String 格式化函数
2023-12-20 10:55 前端小白的江湖路 阅读(338) 评论(0) 编辑 收藏 举报背景
一般我们格式化JSON string是通过JSON.parse, 再使用JSON.stringify方法进行格式化,但是JSON.parse 有BigInt精度丢失问题
方案
考虑用以下纯字符串的方式来解析,添加空格与\n来缩进。
比较易漏的点在于
1.考虑转义字符,
2.字符串内的字符,不需要格式化,需要优先跳过。
/** * * @param jsonStr {string} JSON字符串格式化函数,去除多余的空格,\n等 * @param indentChar {string} 缩进字符,默认为2个空格缩进 * @returns string */ export const jsonPrettier = (jsonStr = "", indentChar = " ") => { if (typeof jsonStr !== "string") { console.warn(`jsonStr: ${jsonStr} 需要为字符串类型`); return jsonStr; } if (typeof indentChar !== "string") { throw new Error(`indentChar: ${indentChar}缩进字符需要为字符串类型`); } let result = ""; let isInString = false; // key, value, array子项 const SPACE_CHAR = " "; const ESCAPE_CHAR = "\\"; let indentLevel = 0; let i = 0; while (i < jsonStr.length) { const item = jsonStr[i]; // 跳过非字符串内的转义字符 if (item === "\n" || item === "\t" || item === "\r" || item === "\b") { i++; continue; } // 字符串内存在转义字符 if (item === ESCAPE_CHAR) { const nextChar = jsonStr[i + 1] ?? ""; result += item + nextChar; i += 2; continue; } if (item === '"') { result += item; isInString = !isInString; i++; continue; } if (isInString) { result += item; i++; continue; } // 不在string中 switch (item) { case SPACE_CHAR: i++; continue; case "{": case "[": result += `${item}\n`; indentLevel += 1; result += indentChar.repeat(indentLevel); break; case "}": case "]": result += "\n"; indentLevel -= 1; result += indentChar.repeat(indentLevel) + item; break; case ",": result += item + "\n"; result += indentChar.repeat(indentLevel); break; case ":": result += item + SPACE_CHAR; break; default: result += item; } i++; } return result; }; const test = (jsonStr = "") => { const a = JSON.stringify(JSON.parse(jsonStr), null, 2); const b = jsonPrettier(jsonStr); console.warn("is equal: ", a === b); console.log(`origin jsonStr: `, jsonStr); console.log("prettier result: ", b); console.log("----------"); if (a !== b) { throw new Error("a与b不相等"); } }; // number string boolean array object null undefined test("100 "); test("true "); test('"abc " '); test('{"a": 10, "b": 100}'); test('["a", "b", "{abcd}\\""]'); test('{ \r "a": 1, "b,,,": \n"bb: b", "c": { "d": 100,\n "e": "abc\\n"}}\n'); test( `{ \r "a": 1, "b,,,": \n "bb: b", "c": \t \t { "d": 100,\n "e": "abc\\n"}}\n` ); test(`{ "a": "a b c" }`);
输出结果: