format-json-string
Version:
format JSON string, download JSON string to file
108 lines (102 loc) • 4.01 kB
JavaScript
const formatJson = (jsonString, indentNum = 2) => {
if (typeof jsonString !== 'string') {
throw new Error('The first parameter of formatJson must be string type.')
}
const PADDING = " ".repeat(indentNum); // 缩进位数,默认为2个空格
/**
* 1. 去除字符串中的空格
*/
jsonString = jsonString.replace(/\s+/g, '');
/**
* 2. 添加回车换行
*/
// 匹配到 { 或 } 在两边添加回车换行
jsonString = jsonString.replace(/([\{\}])/g, "\r\n$1\r\n");
// 匹配到 [ 或 ] 在两边添加回车换行
jsonString = jsonString.replace(/([\[\]])/g, "\r\n$1\r\n");
// 匹配到 , 在后面添加回车换行
jsonString = jsonString.replace(/(\,)/g, "$1\r\n");
// 多行回车换行改为一行回车换行
jsonString = jsonString.replace(/(\r\n\r\n)/g, "\r\n");
// 匹配到单独处于一行的 , 时,去掉换行
jsonString = jsonString.replace(/\r\n\,/g, ",");
/**
* 3. 去除多余的"
*/
let jsonArray = jsonString.split("\r\n");
let indexArr = [];
let indexStart = null;
let indexEnd = null;
jsonArray.forEach((item, index) => {
// 获取当前字符串段中"的数量
let num = item.match(/\"/g) ? item.match(/\"/g).length : 0;
// 判断num是否为奇数来确定是否需要特殊处理
if (num % 2 && !indexStart) {
indexStart = index;
}
if (num % 2 && indexStart && indexStart != index) {
indexEnd = index;
}
// 将需要特殊处理的字符串段的其实位置和结束位置信息存入,并对应重置开始时和结束变量
if (indexStart && indexEnd) {
indexArr.push({
start: indexStart,
end: indexEnd
});
indexStart = null;
indexEnd = null;
}
});
// 开始处理双引号中的内容,将多余的"去除
indexArr.reverse().forEach(function(item, index) {
let newArray = jsonArray.slice(item.start, item.end + 1);
jsonArray.splice(
item.start,
item.end + 1 - item.start,
newArray.join("")
);
});
/**
* 4. 去除多余的回车换行,:后增加空格
*/
jsonString = jsonArray.join("\r\n");
// 匹配到:后为回车换行加大括号替换为冒号加大括号
jsonString = jsonString.replace(/\:\r\n\{/g, ":{");
// 匹配到:后为回车换行加中括号替换为冒号加中括号
jsonString = jsonString.replace(/\:\r\n\[/g, ":[");
// 所有的:后加上空格
jsonString = jsonString.replace(/\:/g, ": ");
/**
* 5. 处理缩进,拼接格式化后的字符串
*/
jsonArray = jsonString.split("\r\n");
let formattedJsonString = "";
let indentCount = 0; // 每一行缩进的次数
jsonArray.forEach(item => {
let currentIndentCount = 0; // 当前行缩进的次数
// 匹配到以 { 或 [ 结尾时缩进次数加1
if (item.match(/\{$/) || item.match(/\[$/)) {
currentIndentCount += 1;
}
// 匹配到以 } 或 ] 结尾时缩进次数减1
if (item.match(/\}$/) || item.match(/\]$/) || item.match(/\},$/) || item.match(/\],$/)) {
indentCount > 0 && (indentCount -= 1);
}
let padding = PADDING.repeat(indentCount); // 该行缩进的空格
formattedJsonString += padding + item + "\r\n";
indentCount += currentIndentCount;
});
return formattedJsonString.trim();
}
const downloadJsonFile = (jsonString, filename = 'download.json') => {
jsonString = formatJson(jsonString);
let aLink = document.createElement("a");
aLink.download = filename;
aLink.style.display = "none";
let blob = new Blob([jsonString]); // 转换成blob类型
aLink.href = URL.createObjectURL(blob);
document.body.appendChild(aLink);
aLink.click();
document.body.removeChild(aLink);
}
export { formatJson, downloadJsonFile };