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

 

声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。