自改的纯V1版本+示例:
JSon.ahk - v2.5 By FeiYue 原版:
;------------------------------------ ; JSon.ahk - v2.5 By FeiYue ; ; v2.5 更新: ; 1、函数兼容 V1、V2,且解析时尽量容错。 ; 2、改进了双引号提取字符串的正则表达式。 ; 3、使用了 true、false、null 对象来恢复Json原样字符串, ; 但是在AHK中读取对应值时要用 “值.value”。 ;------------------------------------ ; JSon字符串转AHK对象 = JSON.Load() json_toobj(s) { static q:=Chr(34), V2:=(A_AhkVersion~="^2") , op:=(V2 ? "" : "O)") , vMap:=(V2 ? "Map" : "Object") , vTrue :=%vMap%("name", "true", "value", 1) , vFalse:=%vMap%("name", "false", "value", 0) , vNull :=%vMap%("name", "null", "value", "") static rep:=[ ["\\","\u005c"], ["\" q,q], ["\/","/"] , ["\r","`r"], ["\n","`n"], ["\t","`t"], ["\b","`b"], ["\f","`f"] ] if !(p:=RegExMatch(s, op "[{\[]", (V2 ? &r : r))) return stack:=[], result:=(V2 && r[0]!="[" ? %vMap%() : []) , arr:=result, isArr:=(r[0]="["), key:=(isArr ? 1 : ""), keyok:=0 While p:=RegExMatch(s, op "\S", (V2 ? &r : r), p+StrLen(r[0])) { Switch r[0] { Case "{", "[": r1:=(V2 && r[0]!="[" ? %vMap%() : []) , (isArr && !keyok ? (arr.Push(r1), keyok:=1) : arr[key]:=r1) , stack.Push(arr, isArr, key, keyok) , arr:=r1, isArr:=(r[0]="["), key:=(isArr ? 1 : ""), keyok:=0 Case "}", "]": if (V2 ? stack.Length : stack.Length())<4 Break keyok:=stack.Pop(), key:=stack.Pop() , isArr:=stack.Pop(), arr:=stack.Pop() Case ",": key:=(isArr ? key+1 : ""), keyok:=0 Case ":": (!isArr && keyok:=1) Case q: re:=op . q "((?:[^" q "\\]*(?:\\[\s\S])?)*)" q if RegExMatch(s, re, (V2 ? &r : r), p)!=p Break if InStr((r1:=r[1]), "\") { For k, v in rep r1:=StrReplace(r1, v[1], v[2]) v:="", k:=1 While i:=RegExMatch(r1, "i)\\u[0-9a-f]{4}",, k) v.=SubStr(r1,k,i-k) . Chr("0x" SubStr(r1,i+2,4)), k:=i+6 r1:=v . SubStr(r1,k) } if (isArr or keyok) (isArr && !keyok ? (arr.Push(r1), keyok:=1) : arr[key]:=r1) else key:=r1 Default: if RegExMatch(s, op "[^\s{}\[\],:" q "]+", (V2 ? &r : r), p)!=p Break Try r1:="", r1:=(r[0]=="true" ? vTrue : r[0]=="false" ? vFalse : r[0]=="null" ? vNull : r[0]+0) (isArr && !keyok ? (arr.Push(r1), keyok:=1) : arr[key]:=r1) } } return result } ; AHK对象转JSon字符串 json_fromobj(obj, space:="") { static q:=Chr(34), V2:=(A_AhkVersion~="^2") , op:=(V2 ? "" : "O)") , vType:="Type" , vIsNumber:="IsNumber" static rep:=[ ["\\","\"], ["\" q,q] ;------------------- ; 默认不替换 "/-->\/" 与 html特殊字符 "<、>、&-->\uXXXX" ; , ["\/","/"], ["\u003c","<"], ["\u003e",">"], ["\u0026","&"] ;------------------- , ["\r","`r"], ["\n","`n"], ["\t","`t"], ["\b","`b"], ["\f","`f"] ] if !IsObject(obj) { if V2 { if %vIsNumber%(obj) return %vType%(obj)="String" ? q . obj . q : obj } else { if obj is Number ; thanks lexikos return [obj].GetCapacity(1) ? q . obj . q : obj } For k, v in rep obj:=StrReplace(obj, v[2], v[1]) ;------------------- ; 默认不替换 "Unicode字符-->\uXXXX" ; While RegExMatch(obj, op "[^\x20-\x7e]", (V2 ? &r : r)) ; obj:=StrReplace(obj, r[0], Format("\u{:04x}",Ord(r[0]))) ;------------------- return q . obj . q } if V2 { isArr:=(%vType%(obj)="Array") if (!isArr and obj.Count=2) and obj.Has("name") and obj.Has("value") and ((k:=obj["name"])=="true" or k=="false" or k=="null") return k } else { isArr:=1 For k, v in obj if (k!=A_Index) and !(isArr:=0) Break if (!isArr and obj.Count()=2) and obj.HasKey("name") and obj.HasKey("value") and ((k:=obj["name"])=="true" or k=="false" or k=="null") return k } s:="", NewSpace:=space . " ", f:=A_ThisFunc For k, v in obj if !(k="" or IsObject(k)) s.= "`r`n" NewSpace . (isArr ? "" : %f%(k . "") ": ") . %f%(v,NewSpace) . "," s:=Trim(s,",") . "`r`n" space return isArr ? "[" s "]" : "{" s "}" } ;=========== 测试代码 ============== s:=" ( { ""name"": ""BeJson"", ""url"": ""http://www.bejson.com"", ""page"": 88, ""page2"": ""88"", ""isNonProfit"": true, ""address"": { ""street"": ""科技园路"", ""city"": ""江苏苏州"", ""country"": ""中国"" }, ""links"": [ { ""name"": ""Google"", ""url"": ""http://www.google.com"" }, { ""name"": ""Baidu"", ""url"": ""http://www.baidu.com"" }, { ""name"": ""SoSo"", ""url"": ""http://www.SoSo.com"" } ] } )" (A_AhkVersion~="^2") && s:=StrReplace(s, (q:=Chr(34)) q, q) ; test(s) 转成对象 := json_toobj(s) ; Debug(转成对象) MsgBox % 转成对象["address"]["city"] "`n`n等效写法:" 转成对象.address.city Return ; 热键测试复制的JSon字符串,重新排版后显示 F1:: test(s:="") { static V2:=(A_AhkVersion~="^2") , vClipboard:=(V2 ? "A_Clipboard" : "Clipboard") if InStr(A_ThisHotkey, "F1") s:=%vClipboard% Critical t1:=A_TickCount obj:=json_toobj(s) t2:=A_TickCount s:=json_fromobj(obj) t3:=A_TickCount Critical 0 %vClipboard%:=s s:="耗时:" (t2-t1) "-" (t3-t2) " ms`n`n" SubStr(s,1,1000) vS:=(V2 ? "s" : s) MsgBox %vS% }
声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。
评论(0)