js實現【JSON格式化】——方式1:正則

bambi發表於2020-03-08

JSON格式化步驟

  1. 識別出有效JSON
  2. 去掉所有空格縮排換行
  3. 識別{},:進行格式化:
    • {},換行
    • :後面加空格
    • 注意要點:JSON的鍵值中,也可能在字串中存在{},:。例如:{"a{},:b": 0}。格式化時需要先排除這部分內容。

JSON去除空格 + 過濾無效JSON

/*
    param1 JSONstr 未格式化的JSON字串
    return 去【類空格字元】後的JSON字串
*/
function JSONTrim(JSONstr) {
    try {
        JSONstr = JSONstr.replace(/'/g, '"');
        JSONstr = JSON.stringify(JSON.parse(JSONstr));
    } catch (error) {
        // 轉換失敗錯誤提示
        console.error('json資料格式有誤...');
        console.error(error);
        JSONstr = null;
    }
    return JSONstr;
}
複製程式碼

JSON格式化

/*
    param1 JSONstr 未格式化的JSON字串
    return 格式化後的JSON字串
*/
function JSONFormat(JSONstr) {
  JSONstr = JSONTrim(JSONstr); // 初步格式化json

  let re = new RegExp('\\{|\\}|,|:', 'g'); // 匹配格式化後的json中的{},:
  let exec = null;
  let InvalidFs = 0;
  let InvalidBs = 0;
  while(exec = re.exec(JSONstr)) { // 找{},:
    let frontToCurrent = exec.input.substr(0, exec.index + 1); // 匹配開頭到當前匹配字元之間的字串
    if (frontToCurrent.replace(/\\"/g, "").replace(/[^"]/g, "").length%2 != 0) { // 測試當前字元到開頭"的數量,為雙數則被判定為目標物件
      if(exec[0] === '{') InvalidFs++;
      else if(exec[0] === '}') InvalidBs++;
      continue; // 不是目標物件,手動跳過
    }
    let keyTimesF = frontToCurrent.replace(/[^\{]/g, '').length - InvalidFs; // 找出當前匹配字元之前所有{的個數
    let keyTimesB = frontToCurrent.replace(/[^\}]/g, '').length - InvalidBs; // 找出當前匹配字元之前所有}的個數
    let indentationTimes = keyTimesF - keyTimesB; // 根據{個數計算縮排

    if (exec[0] === '{') {
      JSONstr = JSONstr.slice(0,exec.index + 1) + '\n' + '\t'.repeat(indentationTimes) + JSONstr.slice(exec.index + 1); // 將縮排加入字串
    } else if(exec[0] === '}') {
      JSONstr = JSONstr.slice(0,exec.index) + '\n' + '\t'.repeat(indentationTimes) + JSONstr.slice(exec.index) // 將縮排加入字串
      re.exec(JSONstr); // 在查詢目標前面插入字串會回退本次查詢,所以手動跳過本次查詢
    } else  if(exec[0] === ',') {
      JSONstr = JSONstr.slice(0,exec.index + 1) + '\n' + '\t'.repeat(indentationTimes) + JSONstr.slice(exec.index + 1)
    } else if (exec[0] === ':') {
      JSONstr = JSONstr.slice(0,exec.index + 1) + ' ' + JSONstr.slice(exec.index + 1)
    } else {
      console.log(`匹配到了來路不明的${exec[0]}`)
    }
  }
  return JSONstr === null ? 'Invalid value' : JSONstr;
}
複製程式碼

示例字串

可以將以下字串打亂格式進行測試,包含了比較複雜的情況

{
	"uu{{{{{{::}},}uc\\\"u": "kkkk",
	"oooooo": {
		
	},
	"pp2": {
		"662": {
			"****": 9
		},
		"k": 88888
	},
	"c___9": true,
	"*": 3
}
複製程式碼

demo

可以點選這裡進行測試,歡迎拍磚!

bambibren.github.io/bejson/inde…

歡迎指教

這是我JSON格式化的思路,希望大家可以多多驗證,指出問題。

相關文章