自改的纯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)