json字串很有用,有時候一些後台介面返回的資訊是字串格式的,可讀性很差,這個時候要是有個可以格式化並高亮顯示json串的方法那就好多了,下面看看一個Regex完成的json字串的格式化與高亮顯示
首先是對輸入進行轉換,如果是對象則轉化為規範的json字串,不是對象時,先將字串轉化為對象(防止不規範的字串),然後再次轉化為json串。其中json為輸入。
if (typeof json !== 'string') {json = JSON.stringify(json);} else {json = JSON.parse(json);json = JSON.stringify(json);}
等規範完資料之後對字串進行標記,為了後面的切分、重新組合
這裡有幾個地方要委任標記,包括大括弧、小括弧的前後和逗號的後面都要委任標記,我這裡使用的是換行\r\n(這樣在命令列下測試時效果會比較好看)。
// 在大括弧前後添加換行reg = /([\{\}])/g;json = json.replace(reg, '\r\n$1\r\n');// 中括弧前後添加換行reg = /([\[\]])/g;json = json.replace(reg, '\r\n$1\r\n');// 逗號後面添加換行reg = /(\,)/g;json = json.replace(reg, '$1\r\n');
添加完成標記之後就要做一些最佳化處理,去掉多餘的換行、去掉逗號前面的換行,這樣做是為了在切分是免得出現空串浪費一次迴圈處理,最後在冒號後面添加空格,看起來更漂亮。
// 去除多餘的換行reg = /(\r\n\r\n)/g;json = json.replace(reg, '\r\n');// 逗號前面的換行去掉reg = /\r\n\,/g;json = json.replace(reg, ',');//冒號前面縮排reg = /\:/g;json = json.replace(reg, ': ');
接下來就是對這個初步處理過的串進行進一步處理了,我會在function(index, node) {}函數中添加邏輯,對每一個切分單元進行處理,包括縮排和美化格式。
$.each(json.split('\r\n'), function(index, node) {});
首先說下縮排,縮排的方法很簡單,遇到{、[符號時縮排增加1,遇到}、]符號時縮排減少1,否則縮排量不變。
//這裡遇到{、[時縮排等級加1,遇到}、]時縮排等級減1,沒遇到時縮排等級不變if (node.match(/\{$/) || node.match(/\[$/)) {indent = 1;} else if (node.match(/\}/) || node.match(/\]/)) {if (pad !== 0) {pad -= 1;}} else {indent = 0;}
完成縮排後就該美化高亮顯示代碼了,這裡要用到幾個css規則,下面可以看到,對切分單元進行高亮顯示的時候這裡用正則進行判斷,如果匹配到大括弧標記為對象class、中括弧標記為數組class、屬性名稱、屬性值,一次對這些進行css規則添加,添加完成之後拼接起來就可以了。
.ObjectBrace{color:#00AA00;font-weight:bold;}.ArrayBrace{color:#0033FF;font-weight:bold;}.PropertyName{color:#CC0000;font-weight:bold;}.String{color:#007777;}.Number{color:#AA00AA;}.Comma{color:#000000;font-weight:bold;} //添加代碼高亮node = node.replace(/([\{\}])/g,"<span class='ObjectBrace'>$1</span>");node = node.replace(/([\[\]])/g,"<span class='ArrayBrace'>$1</span>");node = node.replace(/(\".*\")(\:)(.*)(\,)?/g,"<span class='PropertyName'>$1</span>$2$3$4");node = node.replace(/\"([^"]*)\"(\,)?$/g,"<span class='String'>\"$1\"</span><span class='Comma'>$2</span>");node = node.replace(/(-?\d+)(\,)?$/g,"<span class='Number'>$1</span><span class='Comma'>$2</span>");
最後我們看看完整的方法代碼(這裡我使用了jquery類庫),以及測試地址:
要對jsonstr進行美化,這樣就可以了APP.format(jsonstr),直接輸出至<pre></pre>標籤中就可以看到效果,
下面是一個測試地址,http://iforever.sinaapp.com/ 可以進去試一下,看看完整的原始碼
<script>var APP=function(){var format=function(json){var reg=null,result='';pad=0,PADDING=' ';if (typeof json !== 'string') {json = JSON.stringify(json);} else {json = JSON.parse(json);json = JSON.stringify(json);}// 在大括弧前後添加換行reg = /([\{\}])/g;json = json.replace(reg, '\r\n$1\r\n');// 中括弧前後添加換行reg = /([\[\]])/g;json = json.replace(reg, '\r\n$1\r\n');// 逗號後面添加換行reg = /(\,)/g;json = json.replace(reg, '$1\r\n');// 去除多餘的換行reg = /(\r\n\r\n)/g;json = json.replace(reg, '\r\n');// 逗號前面的換行去掉reg = /\r\n\,/g;json = json.replace(reg, ',');//冒號前面縮排reg = /\:/g;json = json.replace(reg, ': ');//對json按照換行進行切分然後處理每一個小塊$.each(json.split('\r\n'), function(index, node) {var i = 0,indent = 0,padding = '';//這裡遇到{、[時縮排等級加1,遇到}、]時縮排等級減1,沒遇到時縮排等級不變if (node.match(/\{$/) || node.match(/\[$/)) {indent = 1;} else if (node.match(/\}/) || node.match(/\]/)) {if (pad !== 0) {pad -= 1;}} else {indent = 0;}//padding儲存實際的縮排for (i = 0; i < pad; i++) {padding += PADDING;}//添加代碼高亮node = node.replace(/([\{\}])/g,"<span class='ObjectBrace'>$1</span>");node = node.replace(/([\[\]])/g,"<span class='ArrayBrace'>$1</span>");node = node.replace(/(\".*\")(\:)(.*)(\,)?/g,"<span class='PropertyName'>$1</span>$2$3$4");node = node.replace(/\"([^"]*)\"(\,)?$/g,"<span class='String'>\"$1\"</span><span class='Comma'>$2</span>");node = node.replace(/(-?\d+)(\,)?$/g,"<span class='Number'>$1</span><span class='Comma'>$2</span>");result += padding + node + '<br>';pad += indent;});return result;};return {"format":format,};}();</script>
PS:Regex替換json字串的某一項的數字值
aa=aa.replaceAll("\"ccfsID\":\"[0-9]*\"", "\"ccfsID\":\""+id1+"\"");
aa為json字串,如:
{"items":[{"dishprice":30,"ccfsID":"","order.item.id":1,"zuofaid":"","zuofajiajia":0,"isTaoCan":false,"num":1,"price":30,"name":"","ID":"00000001","lsdishID":"","zuofaname":"","tzs":"","addTime":"2013-05-14"}],"deskId":"00000008"}