版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、如何识别一个字符串是否Json格式前言:距离上一篇文章,又过去一个多月了,近些时间,工作依旧很忙碌,除了管理方面的事,代码方面主要折腾三个事:1:开发框架(一整套基于配置型的开发体系框架)2:CYQ.Data 数据层框架(持续的更新,最近也加入了Sybase的支持)3:工作流流程图设计器。由于这三个方面都涉及到Json,所以就谈谈这些天在Json上花下的心思。关于造轮子:很多人对于造轮子都会有自己的看法,这里提一下个人的观点:个人认为:1:首要是要具备造轮子的能力,然后再讨论造不造与浪不浪、轮子与时间的问题。2:造轮子的、写文章的,永远比使用轮子的、看文章的,多经历了一些、多思考一些、多知道一
2、些。所以,别嫌造轮子折腾,虽然的确很折腾,不是有那么句:生命在于折腾,除了瞎折腾。PS:本来文章是写Json常用的功能交互那块相关的知识,所以才有这一段。不多扯了,扯多了都是蛋,还是回归正题吧。如何识别一个字符串是不是Json。网上搜了一下,找到两三个坑人的答案:A:Js识别,Eval一下,成功就是,失败就挂。B:C#识别,判断开始和结束符号:或C:用正则表达式判断。上面ABC答案都纯忽悠,只要认真一下,都不靠谱了。经过我的研究,发现这是有很有挑战性的课题:Json需要分析的情况,比想象的要多,举一个不太简单的Json:1,a:2,rna:, a:,a:,a:2,:3,a:33从上面这个Jso
3、n中,就可以看出需要分析的有:1:数组和Json数组。2:键与值(无引号、双引号)的识别3:无限级值嵌套(数组嵌套、Json嵌套)4:7个关键符号,:。5:转义符号、空格、换行、回车处理。回顾早些年写的JsonHelper还记得CYQ.Data里JsonHelper的最初版本,仅处理了只有一级Json的简单情况,那时候分析Json就靠以下两种方法:1:Split 分隔。2:循环 indexOf 识别。虽然偷工减料,投机取巧,但只要限定使用环境和条件、好在够用,也够简单。当然了,现在情况变了,把限定的环境和条件去除后,事实上,要分析起来就没那么简单了。故事一开始,思考了三天三夜由于放开了条件,需
4、要考虑无限级递归的,于是看似Split和IndexOf这种方式已经不奏效了。字符串的分析方法看似需要改朝换代了,但我仍给Split和IndexOf寻求最后的机会。经过层层思考与分析,发经没折了,只有祭出终极必杀招了。终极大招:遍历字符,记录状态一个万能的解决方法,就是遍历每个字符,然后记录这个字符前后左右上下东南西北中发白各种状态,再根据状态来识别下一个字符的动作。1:首先有一个记录字符状态的类,如下图:这个字符状态的记录类,我前后不断调整了N天,才终于感觉好像OK了。2:接下来是字符的状态设置,根据不同的关键字,设置状态,如下图:这是个漫长不断调试的过程,很折腾人。3:一个可以不断递归Jso
5、n的函数,如下图:4:一个可以识别语法错误的函数:5:最后是一个给外部的调用方法:总结:虽然本文是关于识别Json格式,实际上,它已经是Json解析类的核心,用它可以演化出Json的各种应用,有机会再介绍了。事实上, 一开始是原打算写Json与Xml互转那一块的,写文的意原来自最近一周折腾工作流的流程设计器那一块:从Xml出来到前端成为Json,编辑完后回去又要转回原始格式的Xml存档,所以在Xml和Json间,必须有一套协议,这些,大概是时间不够,所以临时变了一个题目。关于Json的在线解析,以及Json和Xml和互转,临时我开了个域名 :,仅方便自己使用。夜已深,该闭眼去梦里的世界旅游了。
6、最后是本文的源码:1usingSystem;2usingSystem.Collections.Generic;3usingSystem.Text;45namespaceCYQ.Data.Tool67/8/分隔Json字符串为字典集合。9/10internalclassJsonSplit1112privatestaticboolIsJsonStart(refstringjson)1314if(!string.IsNullOrEmpty(json)1516json=json.Trim(r,n,);17if(json.Length1)1819chars=json0;20chare=jsonjson.
7、Length-1;21return(s=&e=)|(s=&e=);222324returnfalse;2526internalstaticboolIsJson(stringjson)2728interrIndex;29returnIsJson(json,outerrIndex);3031internalstaticboolIsJson(stringjson,outinterrIndex)3233errIndex=0;34if(IsJsonStart(refjson)3536CharStatecs=newCharState();37charc;38for(inti=0;i0)4849errInd
8、ex=i+err;50returnfalse;5152i=i+length-1;5354if(cs.isError)5556errIndex=i;57returnfalse;58596061return!cs.arrayStart&!cs.jsonStart;6263returnfalse;646566/67/获取值的长度(当Json值嵌套以或开头时)68/69privatestaticintGetValueLength(stringjson,boolbreakOnErr,outinterrIndex)7071errIndex=0;72intlen=0;73if(!string.IsNullO
9、rEmpty(json)7475CharStatecs=newCharState();76charc;77for(inti=0;ijson.Length;i+)7879c=jsoni;80if(!SetCharState(c,refcs)/设置关键符号状态。8182if(!cs.jsonStart&!cs.arrayStart)/json结束,又不是数组,则退出。8384break;858687elseif(cs.childrenStart)/正常字符,值状态下。8889intlength=GetValueLength(json.Substring(i),breakOnErr,outerrIn
10、dex);/递归子值,返回一个长度。90cs.childrenStart=false;91cs.valueStart=0;92/cs.state=0;93i=i+length-1;9495if(breakOnErr&cs.isError)9697errIndex=i;98returni;99100if(!cs.jsonStart&!cs.arrayStart)/记录当前结束位置。101102len=i+1;/长度比索引+1103break;104105106107returnlen;108109/110/字符状态111/112privateclassCharState113114interna
11、lbooljsonStart=false;/以开始了.115internalboolsetDicValue=false;/可以设置字典值了。116internalboolescapeChar=false;/以转义符号开始了117/118/数组开始【仅第一开头才算】,值嵌套的以【childrenStart】来标识。119/120internalboolarrayStart=false;/以符号开始了121internalboolchildrenStart=false;/子级嵌套开始了。122/123/【0初始状态,或遇到“,”逗号】;【1遇到“:”冒号】124/125internalintsta
12、te=0;126127/128/【-1取值结束】【0未开始】【1无引号开始】【2单引号开始】【3双引号开始】129/130internalintkeyStart=0;131/132/【-1取值结束】【0未开始】【1无引号开始】【2单引号开始】【3双引号开始】133/134internalintvalueStart=0;135internalboolisError=false;/是否语法错误。136137internalvoidCheckIsError(charc)/只当成一级处理(因为GetLength会递归到每一个子项处理)138139if(keyStart1|valueStart1)140
13、141return;142143/示例aa,bbbb:123,fff,ddd144switch(c)145146case:/A:B:3,m:C147isError=jsonStart&state=0;/重复开始错误同时不是值处理。148break;149case:150isError=!jsonStart|(keyStart!=0&state=0);/重复结束错误或者提前结束aa。正常的有151break;152case:153isError=arrayStart&state=0;/重复开始错误154break;155case:156isError=!arrayStart|jsonStart;
14、/重复开始错误或者Json未结束157break;158case:159case:160isError=!(jsonStart|arrayStart);/json或数组开始。161if(!isError)162163/重复开始,164isError=(state=0&keyStart=-1)|(state=1&valueStart=-1);165166if(!isError&arrayStart&!jsonStart&c=)/aa,167168isError=true;169170break;171case:172isError=!jsonStart|state=1;/重复出现。173brea
15、k;174case,:175isError=!(jsonStart|arrayStart);/json或数组开始。176if(!isError)177178if(jsonStart)179180isError=state=0|(state=1&valueStart1);/重复出现。181182elseif(arrayStart)/aa,183184isError=keyStart=0&!setDicValue;185186187break;188case:189caser:190casen:/a,rn191case0:192caset:193break;194default:/值开头。195i
16、sError=(!jsonStart&!arrayStart)|(state=0&keyStart=-1)|(valueStart=-1&state=1);/196break;197198/if(isError)199/200201/202203204/205/设置字符状态(返回true则为关键词,返回false则当为普通字符处理)206/207privatestaticboolSetCharState(charc,refCharStatecs)208209cs.CheckIsError(c);210switch(c)211212case:/A:B:3,m:C213#region大括号214i
17、f(cs.keyStart=0&cs.valueStart=0)215216cs.keyStart=0;217cs.valueStart=0;218if(cs.jsonStart&cs.state=1)219220cs.childrenStart=true;221222else223224cs.state=0;225226cs.jsonStart=true;/开始。227returntrue;228229#endregion230break;231case:232#region大括号结束233if(cs.keyStart=0&cs.valueStart2&cs.jsonStart)234235
18、cs.jsonStart=false;/正常结束。236cs.state=0;237cs.keyStart=0;238cs.valueStart=0;239cs.setDicValue=true;240returntrue;241242/cs.isError=!cs.jsonStart&cs.state=0;243#endregion244break;245case:246#region中括号开始247if(!cs.jsonStart)248249cs.arrayStart=true;250returntrue;251252elseif(cs.jsonStart&cs.state=1)2532
19、54cs.childrenStart=true;255returntrue;256257#endregion258break;259case:260#region中括号结束261if(cs.arrayStart&!cs.jsonStart&cs.keyStart=2&cs.valueStart=0)/,333/这样结束。262263cs.keyStart=0;264cs.valueStart=0;265cs.arrayStart=false;266returntrue;267268#endregion269break;270case:271case:272#region引号273if(cs.j
20、sonStart|cs.arrayStart)274275if(cs.state=0)/key阶段,有可能是数组aa,276277if(cs.keyStart=0)278279cs.keyStart=(c=?3:2);280returntrue;281282elseif(cs.keyStart=2&c=)|(cs.keyStart=3&c=)283284if(!cs.escapeChar)285286cs.keyStart=-1;287returntrue;288289else290291cs.escapeChar=false;292293294295elseif(cs.state=1&cs.
21、jsonStart)/值阶段必须是Json开始了。296297if(cs.valueStart=0)298299cs.valueStart=(c=?3:2);300returntrue;301302elseif(cs.valueStart=2&c=)|(cs.valueStart=3&c=)303304if(!cs.escapeChar)305306cs.valueStart=-1;307returntrue;308309else310311cs.escapeChar=false;312313314315316317#endregion318break;319case:320#region冒号
22、321if(cs.jsonStart&cs.keyStart2&cs.valueStart2&cs.state=0)322323if(cs.keyStart=1)324325cs.keyStart=-1;326327cs.state=1;328returntrue;329330/cs.isError=!cs.jsonStart|(cs.keyStart2&cs.valueStart2&cs.state=1);331#endregion332break;333case,:334#region逗号/aa,aa:12,335336if(cs.jsonStart)337338if(cs.keyStart2&cs.valueStart2&cs.state=1)339340cs.state=0;341cs.keyStart=0;342cs.valueStart=0;343/if(cs.valueStart=1)344/345/cs.va
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 拆船业的可持续发展战略规划考核试卷
- 制鞋业市场产品差异化考核试卷
- 木材的电子与通讯应用考核试卷
- 福建省福州市福清市2024-2025学年六年级上学期期中英语试卷
- 企业知识产权培训方案
- 化学纤维在水利工程领域的应用考核试卷
- 煤矿安全管理与风险预控考核试卷
- 低温低价设备制造技术在铁合金冶炼中的应用考核试卷
- 城市交通管理的案例分析考核试卷
- 2025年中考语文备考之名著复习:《艾青诗选》题集组(答案)
- 医务人员职业暴露预防及处理课件(完整版)
- 期中阶段性练习(一~四单元)(试题)-2024-2025学年五年级上册数学苏教版
- 《病人安全护理学》-教学大纲
- 项目分成比例合同模板
- GB 27887-2024机动车儿童乘员用约束系统
- 期中考试模拟试卷 2024-2025学年人教版数学九年级上册
- 朝鲜半岛局势演变
- 自然科学基金项目申请书
- 第四届全国新能源汽车关键技术技能大赛(新能源汽车轻量化技术方向)决赛参考试题库(含答案)
- 2024年秋新鲁科版三年级上册英语课件 Unit 6 lesson 1
- 教师资格考试小学数学面试试题与参考答案
评论
0/150
提交评论