當前位置:編程學習大全網 - 源碼下載 - 純lua判斷字符串是否是規範的json格式

純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"來判斷格式,如果對妳有幫助的話記得點贊哦

  • 上一篇:《壹起來捉妖》小財神怎麽玩?《壹起來捉妖》小財神都有哪些技能?
  • 下一篇:壹篇文章搞懂unittest單元測試框架
  • copyright 2024編程學習大全網