【原创】json字符串的简易格式化(delphi实现)
由于工作需要,需要将json字符串进行格式化展示,方便手工调试。
在线的工具有很多,但一时没找到离线的库或方法。
因此自己写了个简易规则的格式化方法,集成到开发工具中。
此方法只对字符串做一次遍历,不做json合法性校验,如果格式错误,
整理过程中就可能出现不整齐的情况(例如 缩进错误等)。
闲话少说,上代码:
//json串的简易格式化处理
//输入:
// indent 用来表示缩进的字符串
// inputStr 待格式化的json字符串
//输出:
// 格式化后的json字符串
//
function formatJson(indent : string; inputStr : string) : string;
var
outStr,s : string;
p,i : integer;
c : char;
level : integer; //缩进级别
quot : integer; //双引号标记
slant : integer; //反斜杠标记
colon : integer; //冒号
function getTab(level : integer):string;
var
tab : string;
j : integer;
begin
getTab := '';
if level > 0 then
begin
for j:=1 to level do
begin
tab := tab + indent;
end;
end;
result := tab;
end;
begin
//去掉换行回车符
inputStr := stringReplace(inputStr,#13#10,'',[rfReplaceAll, rfIgnoreCase]);
//去掉tab符
inputStr := stringReplace(inputStr,#9,'',[rfReplaceAll, rfIgnoreCase]);
//支持 xxx={...} 格式的数据,保留 xxx= 内容。
p := pos('{',inputStr);
if p>0 then
begin
outStr := copy(inputStr,1,p-1);
inputStr := copy(inputStr,p,length(inputStr));
end
else
begin
result := inputStr;
exit;
end;
//json格式化处理
//简易处理规则:
//遇到反斜杠 "\",输出,后面紧跟的字符直接输出,不做特殊处理
//遇到双引号 """,输出,等待匹配下一个双引号(除了反斜杠"\"后的双引号外),其间的字符直接输出
//遇到左花括号 "{" 缩进不变输出,回车,后续缩进等级+1
//遇到右花括号 "}" 回车,缩进-1, 输出,后续缩进等级-1
//遇到左方括号 "[" 缩进不变输出,回车,后续缩进等级+1
//遇到右方括号 "]" 回车,缩进-1, 输出,后续缩进等级-1
//遇到双引号外的逗号 "," 输出后回车
//遇到冒号 ":", 输出,加一个空格
//不符合以上规则的字符,除空格外,直接 输出
level := 0;
quot := 0; //是否等待匹配双引号
colon := 0;
for i:=1 to length(inputStr) do
begin
c := inputStr[i];
if c<>' ' then s:=c else s:=''; //过滤一般性空格
if (slant=1) then
begin
//反斜杠之后的字符直接输出
slant := 0;
end
else if (quot = 1) and (c <> '"') and (c<>'\') then
begin
//双引号之后的字符直接输出
s := c; //双引号之间的空格也保留输出
end
else
begin
case c of
'\': begin
slant := 1;
end;
'{': begin
if colon <> 1 then s:=getTab(level) + s ;
s := s + #13#10 ;
level:=level+1;
colon := 0;
end;
'}': begin
s := #13#10 + getTab(level-1) + s;
level:=level-1;
end;
'[': begin
if colon <> 1 then s:=getTab(level) + s ;
s := s + #13#10 ;
level:=level+1;
colon := 0;
end;
']': begin
s := #13#10 + getTab(level-1) + s;
level:=level-1;
end;
'"': begin
quot := 1 - quot;
if (quot=1) and (colon =0 ) then s := getTab(level) + s;
colon := 0;
end;
',': begin
s := s + #13#10 ;
colon := 0;
end;
':': begin
s := s + ' ' ;
colon := 1;
end;
else
//
end ;
end;
outStr := outStr + s;
end;
result := outStr;
end;
//使用样例
procedure test()
var
is ,os: string;
begin
is := '{"appId":null,"timestamp":"20160910122321","messageId":"80e5adaec47d41748628e1715d903ad0","content":{"pub":{"operator":"meizi","requestSource":"20","dataLimit":"1"},"inputPara":[{"parent_id":"0"},{"parent_id":"1"}]}}';
os := formatJson(' ', is);
ShowMessage(os);
end;
//输出
{
"appId": null,
"timestamp": "20160910122321",
"messageId": "80e5adaec47d41748628e1715d903ad0",
"content": {
"pub": {
"operator": "meizi",
"requestSource": "20",
"dataLimit": "1"
},
"inputPara": [
{
"parent_id": "0"
},
{
"parent_id": "1"
}
]
}
}
由于工作需要,需要将json字符串进行格式化展示,方便手工调试。
在线的工具有很多,但一时没找到离线的库或方法。
因此自己写了个简易规则的格式化方法,集成到开发工具中。
此方法只对字符串做一次遍历,不做json合法性校验,如果格式错误,
整理过程中就可能出现不整齐的情况(例如 缩进错误等)。
闲话少说,上代码:
//json串的简易格式化处理
//输入:
// indent 用来表示缩进的字符串
// inputStr 待格式化的json字符串
//输出:
// 格式化后的json字符串
//
function formatJson(indent : string; inputStr : string) : string;
var
outStr,s : string;
p,i : integer;
c : char;
level : integer; //缩进级别
quot : integer; //双引号标记
slant : integer; //反斜杠标记
colon : integer; //冒号
function getTab(level : integer):string;
var
tab : string;
j : integer;
begin
getTab := '';
if level > 0 then
begin
for j:=1 to level do
begin
tab := tab + indent;
end;
end;
result := tab;
end;
begin
//去掉换行回车符
inputStr := stringReplace(inputStr,#13#10,'',[rfReplaceAll, rfIgnoreCase]);
//去掉tab符
inputStr := stringReplace(inputStr,#9,'',[rfReplaceAll, rfIgnoreCase]);
//支持 xxx={...} 格式的数据,保留 xxx= 内容。
p := pos('{',inputStr);
if p>0 then
begin
outStr := copy(inputStr,1,p-1);
inputStr := copy(inputStr,p,length(inputStr));
end
else
begin
result := inputStr;
exit;
end;
//json格式化处理
//简易处理规则:
//遇到反斜杠 "\",输出,后面紧跟的字符直接输出,不做特殊处理
//遇到双引号 """,输出,等待匹配下一个双引号(除了反斜杠"\"后的双引号外),其间的字符直接输出
//遇到左花括号 "{" 缩进不变输出,回车,后续缩进等级+1
//遇到右花括号 "}" 回车,缩进-1, 输出,后续缩进等级-1
//遇到左方括号 "[" 缩进不变输出,回车,后续缩进等级+1
//遇到右方括号 "]" 回车,缩进-1, 输出,后续缩进等级-1
//遇到双引号外的逗号 "," 输出后回车
//遇到冒号 ":", 输出,加一个空格
//不符合以上规则的字符,除空格外,直接 输出
level := 0;
quot := 0; //是否等待匹配双引号
colon := 0;
for i:=1 to length(inputStr) do
begin
c := inputStr[i];
if c<>' ' then s:=c else s:=''; //过滤一般性空格
if (slant=1) then
begin
//反斜杠之后的字符直接输出
slant := 0;
end
else if (quot = 1) and (c <> '"') and (c<>'\') then
begin
//双引号之后的字符直接输出
s := c; //双引号之间的空格也保留输出
end
else
begin
case c of
'\': begin
slant := 1;
end;
'{': begin
if colon <> 1 then s:=getTab(level) + s ;
s := s + #13#10 ;
level:=level+1;
colon := 0;
end;
'}': begin
s := #13#10 + getTab(level-1) + s;
level:=level-1;
end;
'[': begin
if colon <> 1 then s:=getTab(level) + s ;
s := s + #13#10 ;
level:=level+1;
colon := 0;
end;
']': begin
s := #13#10 + getTab(level-1) + s;
level:=level-1;
end;
'"': begin
quot := 1 - quot;
if (quot=1) and (colon =0 ) then s := getTab(level) + s;
colon := 0;
end;
',': begin
s := s + #13#10 ;
colon := 0;
end;
':': begin
s := s + ' ' ;
colon := 1;
end;
else
//
end ;
end;
outStr := outStr + s;
end;
result := outStr;
end;
//使用样例
procedure test()
var
is ,os: string;
begin
is := '{"appId":null,"timestamp":"20160910122321","messageId":"80e5adaec47d41748628e1715d903ad0","content":{"pub":{"operator":"meizi","requestSource":"20","dataLimit":"1"},"inputPara":[{"parent_id":"0"},{"parent_id":"1"}]}}';
os := formatJson(' ', is);
ShowMessage(os);
end;
//输出
{
"appId": null,
"timestamp": "20160910122321",
"messageId": "80e5adaec47d41748628e1715d903ad0",
"content": {
"pub": {
"operator": "meizi",
"requestSource": "20",
"dataLimit": "1"
},
"inputPara": [
{
"parent_id": "0"
},
{
"parent_id": "1"
}
]
}
}