版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 家居装璜代理合同范例
- 吉林省公主岭市2025届高考数学一模试卷含解析
- 内蒙古自治区呼和浩特市第六中学2025届高考语文倒计时模拟卷含解析
- 海南省三亚华侨学校2025届高三下学期联考语文试题含解析
- 2025届山东省潍坊市昌乐、临朐等四县高考英语必刷试卷含解析
- 2025届黑龙江龙江二中高三第三次模拟考试数学试卷含解析
- 泰州市重点中学2025届高考仿真模拟英语试卷含解析
- 浙江省舟山市重点中学2025届高三下学期第六次检测英语试卷含解析
- 2025届甘肃省酒泉市瓜州县高三最后一模数学试题含解析
- 2025届江苏省南京高三第三次模拟考试英语试卷含解析
- 中医操作评分表
- 冯晓霞教授的《幼儿学习品质观察评定表》
- 手工焊接作业指导书
- 拱桥悬链线计算表
- 半年分析----住院超过30天患者原因分析及改进措施
- 无公害农产品查询
- 国家公派出国留学经验交流PPT课件
- 研究生课程应用电化学(课堂PPT)
- 六宫数独可直接打印共192题
- 班会:如何克服浮躁心理PPT优秀课件
- Monsters歌词下载,Monsters原唱歌词中文翻译,Monsters简谱KatieSky
评论
0/150
提交评论