首页 > 编程知识 正文

复杂json源码,复杂json数组解析

时间:2024-03-07 18:23:40 阅读:332210 作者:WBOO

本文目录一览:

求asp编辑JSON数据文件的类源码

asp支持jscript 所以js写的代码在asp里大部分都能运行

%'默认vbscript,可以用jscript定义的函数变量

str="{}"'假设你把文件读出来了,读文件很简单的

set obj=evalJs("("+str+")")'解析json

addJs obj,"value","abcd"'添加内容

addJs obj,"value",true'修改value=true

evalJs "obj.obj={key1:true,key2:[]}"'添加对象 强大的asp多语言支持

delete obj.obj,"key1"'删除key1

evalJs("delete obj.obj")'删除obj

delete obj,"value"'删除value

str=JSON.stringify(obj)'生成json串,这里的JSON.stringify是从json官网下的json2.js文件中的方法,把json2.js下过来把代码插到下面。

'json2.js下载地址底下 javascript json2.js

'....保存str到文件,很简单的

%

script runat="server" language="jscript"//服务器运行jscript,代码无论放哪里都比默认vbscript%%内脚本先执行,如果language="vbscript"就在%%内脚本后执行

//下载的json2.js代码插到这里

function evalJs(json){//转换对象

    return eval(json);

}

function addJs(obj,key,value){//添加修改

    obj[key]=value;

}

function delJs(obj,key){//删除

    delete obj[key];

}

/script

ThinkPHP 生成下面格式json!求大侠给源码!

$a = mysql_query(“select * from 表");

json_encode($a);

//输出看看

print_r($a);

用原始方法解析复杂字符串,json一定要用JsonMapper么

1.不规则非json字符串

先看看这个例子,字符串是连在一起,没有换行的,为了方便观察,换行了,程序是原始在一起的:

[11101630,1532,14,'0','0',3,'2015,4,23,16,05,48','4',1,2,0,0],

[11101631,1532,14,'0','0',3,'2015,4,23,16,09,48','0',,,0,0],

[11101632,1532,14,'0','0',3,'2015,4,23,16,03,10','1',2,2,0,0]

先来分析一下这个字符串的特点,才能找到思路哦:

1.每一组数据都是在[]括号对中,每一组数据用,号分割,所以最终要形成一个数组来访问哦。

2.每一组的数据基本都是用 , 号分割,字符串类型还有单引号 ;

3.第7个数组是一个整体,也使用,号分割,整体是字符串有引号;

4.第2组数据有空值,直接用,号分割,所以splite的时候不能去掉空值,否则数组长度不一样,定位就乱了。

既然分析都完了,那思路呢?

1.组直接分割使用 ], 标记,然后每一组要Repalce掉 [ 和 ] 。主要是最前和最后;

2.组内分割,使用 ,号标记分割,出来之前要把单引号给 替换掉 ;不然也是作为字符串,引号也包括进去了;

3.至于那个 数组 的处理,不能过于想复杂,分割之后,直接在最后增加1个元素,将固定位置7-12的组合起来;这样也许方便点;

4.由于空值有占位,所以每一组的长度是固定的。所以处理的时候直接根据自己想要的位置来组合。

下面看看代码了,C#版本,相对与一行代码,仔细看,Linq很是一个神器,真的是神奇。。。说多了都是泪,为啥就没早点学呢:

String str = @"[11101630,1532,14,'0','0',3,'2015,4,23,16,05,48','4',1,2,0,0],[11101631,1532,14,'0','0',3,'2015,4,23,16,09,48','0',,,0,0],[11101632,1532,14,'0','0',3,'2015,4,23,16,03,10','1',2,2,0,0]";

var result = str.Split(new string[] { "]," }, StringSplitOptions.None) //先整体分割组

.Select(n = n.Replace("[", "") //以下是组内分割,并去掉其他干扰字符

.Replace("]", "")

.Replace("'", "")

.Split(',').ToList())

.Select(n = //对中间一个整体单独提取,进行组合,单独增加一个元素

{

n.Add(String.Format("{0},{1},{2},{3},{4},{5}", n[6], n[7], n[8], n[9], n[10], n[11]));return n;

}).ToList();

看看结果怎么样:

2.键值对字符串分割函数

由于json数据格式都是键值对字符串,所以这里特意分享一个经常用到的分割函数,不用Json组件,那就用简单的方法做一个。这个函数来源于 Newlife.Core ,是 X组件 的重要部分。源码部分不过多解释,就是按规则将键值对直接分割保持在字典中,使用方法大家可以自己实验一下,或者参考下面的案例,都有用到这个方法。代码如下,为了方便使用,写成了扩展方法:

public static class StringHelper

{

/// summary拆分字符串成为名值字典/summary

/// param name="str"要分割字符串的/param

/// param name="nameValueSeparator"键值对的分隔符/param

/// param name="separators"分割字符/param

/// returns键值对字典/returns

public static IDictionaryString, String SplitAsDictionary(this String str, String nameValueSeparator = "=", params String[] separators)

{

var dic = new DictionaryString, String();

if (String.IsNullOrWhiteSpace(str)) return dic;

if (String.IsNullOrEmpty(nameValueSeparator)) nameValueSeparator = "=";

if (separators == null || separators.Length 1) separators = new String[] { ",", ";" };

String[] ss = str.Split(separators, StringSplitOptions.RemoveEmptyEntries);

if (ss == null || ss.Length 1) return null;

foreach (var item in ss)

{

Int32 p = item.IndexOf(nameValueSeparator);

// 在前后都不行

if (p = 0 || p = item.Length - 1) continue;

String key = item.Substring(0, p).Trim();

dic[key] = item.Substring(p + nameValueSeparator.Length).Trim();

}

return dic;

}

}

上面默认的键值对分割符号为 = 号,根据实际情况进行修改,json格式里面一般是:冒号比较多。

3.复杂Json格式的字符串

上面的例子比较简单,这次看一个稍微复杂点的,虽然可能用JsonMapper可以很轻易做到,但试一下最原始的方法吧。还是按照上面的思路,先分析字符串的特点: 字符串是连在一起,没有换行的,为了方便观察,换行了,程序是原始在一起的:

{1074:['墨联','墨联','MEX D1','#098000','98'],

2100:['美乙','美乙','USL D2','#E89B10','98'],

1024:['阿甲','阿甲','ARG','#00CCFF','98'],

1052:['哥伦甲','哥伦甲','COLCMA','#888500','98'],

1028:['K联赛','K联赛','KORL','#F75000','98'],

1297:['球会友谊','球会友谊','CF','#5691D8','98'],

2085:['奥女甲','奥女甲','AFB','#D86220','97']}

还是先分析特点,这个格式应该是json类似的了,比较规则:

组与之间是使用 , 号分割;前后有{}括号对;观察前后可以使用 ], 字符串将组分开;

键 是整数,键值是通过 : 号分割;

值是一个数组,有5个元素,通过 , 号分割

都有单引号,需要过滤掉;其他没有特殊情况;

代码解决过程:

string text = @"{1074:['墨联','墨联','MEX D1','#098000','98'],2100:['美乙','美乙','USL D2','#E89B10','98'],1024:['阿甲','阿甲','ARG','#00CCFF','98'],1052:['哥伦甲','哥伦甲','COLCMA','#888500','98'],1028:['K联赛','K联赛','KORL','#F75000','98'],1297:['球会友谊','球会友谊','CF','#5691D8','98'],2085:['奥女甲','奥女甲','AFB','#D86220','97']}";

var dic = text.Replace("'", "").Split(new String[]{"],"}, StringSplitOptions.None) //先组分割

.Select(n = n.Replace("{", "").Replace("}", "") //将组里面的干扰字符过滤掉

.Replace("[", "").Replace("]", "")

.SplitAsDictionary(":", """) //键值对处理,冒号分隔符

.ToDictionary(t = t.Key, t = t.Value.Split(',')//值再次进行分割,形成数组

)).ToArray();

看看结果如何:

纯lua判断字符串是否是规范的json格式

楼主参考这个:网页链接

最近发现解码json串时,如果json串本身格式错误会造成程序报错,那当然不能忍,于是断断续续抽着间隙来写写了一个礼拜终于写了一个较为完整的纯lua脚本来判断json串。

  因为json用的不是很多,刚开始只是了解到这样的格式: {“a”:“1”,“b”:“2”,“c”:"3"},还有复杂一点的这种:{ "links": [

{  "a": "1",  "b": "2" },

      { "c": "3","d": "4"

      }]},对于这种,一开始我想的处理方式是先找[..] 然后截取出来,再找{...}然后找逗号",",截取逗号前部分后后部分,利用到string.gsub判断这一小段是不是 "a":"1"这样的格式,源码如下,后面还有处理无限嵌套json的源码:

--判断是否是json

function ifIsJson(jsonString)

local head

local pos1,pos2

jsonString =jsonString:atrim()

local String1=string.sub(jsonString,1,1)  --最外部大括号

local String2 = string.sub(jsonString,#jsonString)

if String1=="{" and String2 =="}" then

String1=jsonString

jsonString=string.sub(jsonString,2,-2)  --去掉最外部括号

pos1,_=string.find(jsonString,"%[")  

if pos1 then

pos2,_ = string.find(jsonString,"%]")

if pos2 then

head=string.sub(jsonString,2,pos1-1)

local a,b=string.gsub(head,"("-)(.-)("-):","")

if a =="" and b==1 then

head=string.sub(jsonString,pos1+1,pos2-1)

while true do

if (pos2)==#jsonString then  --没有后续的了

local result= ContinueCheck(head)  --传入 []里的内容

if result then return true else return false end

else --还有

local result= ContinueCheck(head)  --传入 []里的内容

if result== false then return false end

jsonString=string.sub(jsonString,pos2+1,#jsonString) --记录下后面部分

pos1,_=string.find(jsonString,"%[")  

if pos1 then

pos2,_ = string.find(jsonString,"%]")

if pos2 then

head=string.sub(jsonString,2,pos1-1)

local a,b=string.gsub(head,"("-)(.-)("-):","")

if a ~="" and b~=1 then return false end  -- "head":[{....},{.....},{.....}]  其中的head格式不正确

head=string.sub(jsonString,pos1+1,pos2-1)  --下一次循环传入的参数

else

return false--缺少]

end

else

return false --[]缺少[]

end

end

end

else

return false -- "head":[{....},{.....},{.....}]  其中的head格式不正确

end

else

return false  --不匹配[]

end

else --没有中括号,简单的单个{}json处理

local result =ContinueCheck(String1)

if result then return true else return false end

end

else

return false  --不匹配{}

end

end

function ContinueCheck(jsonString)

local stringLength=#jsonString

local pos1,pos2=0,0

local JsonTable={}

local i=1

while (true) do   --截取{....}并且存入表JsonTable中

pos1,_=string.find(jsonString,"{",pos1+1)

if pos1 then

pos2,_=string.find(jsonString,"}",pos2+1)

if pos2 then

JsonTable[i]=string.sub(jsonString,pos1+1,pos2-1)

else

return false

end

else

return false

end

if pos2==#jsonString then break end 

i=i+1

end

local a,b

local j=1

while (true) do

jsonString=JsonTable[j]  --一个一个值检查

while (true) do

local q,_=string.find(jsonString,",")

if q~= nil then --"a":"i","b":"j"找这之间的逗号

local jsonString2=string.sub(jsonString,1,q-1)  --,号前

jsonString=string.sub(jsonString,q+1,#jsonString)  --,号后

a,b=string.gsub(jsonString2,"("-)(.-)("-):","")

else   --没有则为key:value 的最后一个

a,b=string.gsub(jsonString,"("-)(.-)("-):","")

end

if  b==1 then 

a,b=string.gsub(a,"("-)(.+)("+)","")

if a==""  then

mSleep(10)

else

a=tonumber(a)

if type(a) == "number" then

mSleep(10)

else

return false

end

end

else

return false

end

if q == nil then --找到最后啦

break

end

end

if j==i then return true end

j=j+1

end

end

其中msleep只是封装的等待,可以看出这样写的会嵌套超多层,也就我这种格式规范对的整整齐齐的才看得清,不过勉强作为上述简单的json判断还是没问题的,但是后来考虑到如果json有嵌套,一直嵌套[..]和{..}那要怎么办呢,明显这种从{..}中从前到后截取判断的方法是不实用的,然后又花了几天写了一个可以判断任意嵌套的封装函数,有点长还没做优化但是已经可以正常使用了,代码如下:

function ifIsJson(JsonString)

local pos1,pos2,pos3,pos4=0,0,0,0

local counter1,counter2,counter3,counter4=0,0,0,0

local string1,string2

local Mytable,Mytable2={},{}

local i,j=1,1

JsonString=JsonString:atrim()

string1=string.sub(JsonString,1,1)

string2=string.sub(JsonString,-1,-1)

if string1=="{" and string2=="}" then --查看各种括号是否成对存在

_,pos1=string.gsub(JsonString,"{","{")  

_,pos2=string.gsub(JsonString,"}","}")

_,pos3=string.gsub(JsonString,"%[","[")

_,pos4=string.gsub(JsonString,"%]","]")

if pos1~=pos2 or pos3~=pos4 then return false end

else return false end

while (true) do

pos1,pos2=string.find(JsonString,",%[{",pos1)-- 找 ,[{ 找到后找 }]

if pos1 then

pos3,pos4=string.find(JsonString,"}]",pos4)

if pos3 then

string1=string.sub(JsonString,pos1,pos4)

_,counter1=string.gsub(string1,"{","{")  --查看各种括号是否成对存在

_,counter2=string.gsub(string1,"}","}")

_,counter3=string.gsub(string1,"%[","[")

_,counter4=string.gsub(string1,"%]","]")

if counter1 == counter2 and counter3== counter4 then

Mytable[i]=string.sub(JsonString,pos2,pos3) --{....}

i=i+1

string1=string.sub(JsonString,1,pos1-1)

string2=string.sub(JsonString,pos4+1)

JsonString=string1..string2 -- 去掉,{[..}]

pos4=pos1

end

else return false end

else 

pos1,pos2,pos3,pos4=1,1,1,1

pos1,pos2=string.find(JsonString,"%[{") --找[{ 找到后找 }]没有则跳出

if pos1 then

pos3,pos4=string.find(JsonString,"}]")

if pos3 then

string1=string.sub(JsonString,pos1,pos4)

_,counter1=string.gsub(string1,"{","{")  --查看各种括号是否成对存在

_,counter2=string.gsub(string1,"}","}")

_,counter3=string.gsub(string1,"%[","[")

_,counter4=string.gsub(string1,"%]","]")

if counter1 == counter2 and counter3== counter4 then

Mytable[i]=string.sub(JsonString,pos2,pos3) --{....}

i=i+1

string1=string.sub(JsonString,1,pos1-1)

string2=string.sub(JsonString,pos4+1)

JsonString=string1..""""..string2 -- 去掉,[{..}]

pos4=pos1

end

else return false end

else break end

end

end

i=i-1

if Mytable[i]~= nil then

pos1,pos2,pos3,pos4=1,1,1,1

while (true) do  --截取嵌套n层的最里面的[{.....}]

repeat       -- 找table[]中[{最靠后的这符号,

pos1,pos2=string.find(Mytable[i],"%[{",pos2)

if pos1 then pos3,pos4=pos1,pos2  end

until pos1==nil

pos1,pos2=string.find(Mytable[i],"}]",pos4)  --找串中pos4之后}]最靠前的这个符号

if pos1 then

Mytable2[j]=string.sub(Mytable[i],pos4,pos1) --[ {....} ]

j=j+1

string1=string.sub(Mytable[i],1,pos3-1)

stirng2=string.sub(Mytable[i],pos2+1)

Mytable[i]=string1..""""..string2

else 

Mytable2[j]=Mytable[i]

j=j+1

i=i-1

if i== 0 then break end--直到找不到成对的[{}]

end

pos2=1

end

end

Mytable2[j]=JsonString

i=1

Mytable={}

pos1,pos2,pos3,pos4=0,0,1,1

while (true) do

repeat

pos1,_=string.find(Mytable2[j],"{",pos2+1)

if pos1 then pos2=pos1 end

until pos1 == nil 

pos3,_=string.find(Mytable2[j],"}",pos2)

if pos3 and pos2~=1 then

Mytable[i]=string.sub(Mytable2[j],pos2,pos3) --  {...}

i=i+1

string1=string.sub(Mytable2[j],1,pos2-1)

string2=string.sub(Mytable2[j],pos3+1)

Mytable2[j]=string1..""""..string2

else

Mytable[i]=string.sub(Mytable2[j],1,pos3)

i=i+1

j=j-1

if j==0 then break end

end

pos2=0

-- 串b截取   {  "id":"243125b4-5cf9-4ad9-827b-37698f6b98f0" }  这样的格式 存进table[j]

-- 剩下一个 "image":{ "id":"243125b4-5cf9-4ad9-827b-37698f6b98f0","a":"e0", "d":"2431-f6b98f0","f":"243125b98f0"--}这样的也存进table[j+1]

end

i=i-1

for n=1,i do  --去除{}

Mytable[n]=string.sub(Mytable[n],2,-2)

end

while (true) do

pos1,_=string.find(Mytable[i],",")

if pos1~= nil then --"a":"i","b":"j"找这之间的逗号

string1=string.sub(Mytable[i],1,pos1-1)--,前

Mytable[i]=string.sub(Mytable[i],pos1+1)

pos2,_=string.find(string1,""")

if pos2==1 then

pos3,pos4=string.find(string1,"":",2)

if pos3 then

string2=string.sub(string1,pos4+1)

else 

--("发现错误1", 1)

return false

end

else 

--("发现错误2", 1)

return false

end

else

pos2,_=string.find(Mytable[i],""")

if pos2==1 then

pos3,pos4=string.find(Mytable[i],"":",2)

if pos3 then

string2=string.sub(Mytable[i],pos4+1)

else

--("发现错误3", 1)

return false

end

else 

--("发现错误4", 1)

return false

end

end

pos2,pos3=string.gsub(string2,"("-)(.+)("+)","")

if pos2=="" or pos2 == "null" then

--("这一个串格式正确", 2)

else

pos2=tonumber(pos2)

if type(pos2) == "number" then

--("这一个串格式正确2", 2)

else

--("发现错误5", 1)

return false

end

end

if pos1== nil then

i=i-1

if i==0 then return true end

end

end

end

这里有一个很核心的思想是既然是无限嵌套都要判断的出来,那么脚本要做到的是获取到最最里面的{..}单层结构的json,博猪是通过找最后的[ 和{ ,然后在此位置之后找最靠近的]和},截取出来后依然是按逗号截取出最小部分"a":"1"来判断格式,如果对你有帮助的话记得点赞哦

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。