使用 AutoHotkey 解析、生成和美化/格式化 Json?
Posted
技术标签:
【中文标题】使用 AutoHotkey 解析、生成和美化/格式化 Json?【英文标题】:Json parsing, generating and beautifiying / formatting with AutoHotkey? 【发布时间】:2016-03-03 12:35:22 【问题描述】:如何将 json 字符串转换为自动热键对象/数组...反之亦然?以及如何使用换行符和空格缩进很好地格式化 json 字符串?
【问题讨论】:
这是一个自我回答的问题!没有理由拒绝它! 【参考方案1】:这是我最近写的一个 Json 类。它会自动处理缩进和换行符。您甚至可以指定要使用的字符等。 它还处理字符串中的双引号等边缘情况(它们需要在 json 中转义),这是我在 ahk 中的其他 json 函数中真正缺少的东西。
class Json
__New(indent=" ",newLine="`r`n") ;default indent: 4 spaces. default newline: crlf
this.ind := indent
this.nl := newLine
getIndents(num)
indents := ""
Loop % num
indents .= this.ind
Return indents
jsonFileToObj(fileFullPath)
file := FileOpen(fileFullPath, "r")
Return this.jsonToObj(file.Read()), file.Close()
objToJsonFile(obj,fileFullPath)
FileDelete, % fileFullPath
SplitPath, fileFullPath,, dir
FileCreateDir % dir
file := FileOpen(fileFullPath, "w")
Return file.write(this.objToJson(obj)), file.Close()
objToJson(obj,indNum:=0)
indNum++
str := "" , array := true
for k in obj
if (k == A_Index)
continue
array := false
break
for a, b in obj
str .= this.getIndents(indNum) . (array ? "" : """" a """: ") . (IsObject(b) ? this.objToJson(b,indNum) : this.isNumber(b) ? b : """" StrReplace(b,"""","\""") """") . ", " this.nl
str := RTrim(str, " ," this.nl)
return (array ? "[" this.nl str this.nl this.getIndents(indNum-1) "]" : "" this.nl str this.nl this.getIndents(indNum-1) "")
jsonToObj(jsonStr)
SC := ComObjCreate("ScriptControl")
SC.Language := "JScript"
ComObjError(false)
jsCode =
(
function arrangeForAhkTraversing(obj)
if(obj instanceof Array)
for(var i=0 ; i<obj.length ; ++i)
obj[i] = arrangeForAhkTraversing(obj[i]) ;
return ['array',obj] ;
else if(obj instanceof Object)
var keys = [], values = [] ;
for(var key in obj)
keys.push(key) ;
values.push(arrangeForAhkTraversing(obj[key])) ;
return ['object',[keys,values]] ;
else
return [typeof obj,obj] ;
)
SC.ExecuteStatement(jsCode "; obj=" jsonStr)
return this.convertJScriptObjToAhkObj( SC.Eval("arrangeForAhkTraversing(obj)") )
convertJScriptObjToAhkObj(jsObj)
if(jsObj[0]="object")
obj := , keys := jsObj[1][0], values := jsObj[1][1]
loop % keys.length
obj[keys[A_INDEX-1]] := this.convertJScriptObjToAhkObj( values[A_INDEX-1] )
return obj
else if(jsObj[0]="array")
array := []
loop % jsObj[1].length
array.insert(this.convertJScriptObjToAhkObj( jsObj[1][A_INDEX-1] ))
return array
else
return jsObj[1]
isNumber(Num)
if Num is number
return true
else
return false
方法列表:
json.jsonFileToObj(fileFullPath) ;convert a json file into an ahk object
json.objToJsonFile(obj,fileFullPath) ;convert an ahk object into a json file
json.objToJson(obj) ;convert an object into a json string
json.jsonToObj(jsonStr) ;convert a json string into an ahk object
例子:
json := new Json(" ", "`r`n") ;use 2 space indentation and CR LF for new lines
testObject := "key":"","key2":"val2",keyWithoutQuotes:"val3","myArray":["a1","a2","a3","myEdgeCase":"edge case ""test""","numberValue":2]
MsgBox % json.objToJson(testObject)
输出:
"key": "",
"key2": "val2",
"keyWithoutQuotes": "val3",
"myArray": [
"a1",
"a2",
"a3",
"myEdgeCase": "edge case \"test\"",
"numberValue": 2
]
另外还有Coco's Json Class,你一定要看看。它可能是代码的 4 倍,但它确实有一些有趣的功能。
【讨论】:
【参考方案2】:我使用以下功能,目前为止非常适合我。没有文件处理,而是自己决定方向:
json(i)
;ENCODE
if (isobject(i))
o := "", a := 1, x := 1
for k,v in i
if (k!=x)
a := 0, break
x += 1
o .= (a) ? "[" : "", f := 1
for k,v in i
o .= ((f) ? "" : ",")((a) ? "" : """" k """:")((isobject(v)) ? json(v) : ((v+0=v) ? v : """" v """")), f := 0
return o ((a) ? "]" : "")
;DECODE
if (regexmatch(i, "s)^__chr(A|W):(.*)", m))
VarSetCapacity(b, 4, 0), NumPut(m2, b, 0, "int")
return StrGet(&b, 1, (m1="A") ? "cp28591" : "utf-16")
if (regexmatch(i, "s)^__str:((\\""|[^""])*)", m))
str := m1
for p,r in b:"`b", f:"`f", n:"`n", 0:"", r:"`r", t:"`t", v:"`v", "'":"'", """":"""", "/":"/"
str := regexreplace(str, "\\" p, r)
while (regexmatch(str, "s)^(.*?)\\x([0-9a-fA-F]2)(.*)", m))
str := m1 json("__chrA:0x" m2) m3
while (regexmatch(str, "s)^(.*?)\\u([0-9a-fA-F]4)(.*)", m))
str := m1 json("__chrW:0x" m2) m3
while (regexmatch(str, "s)^(.*?)\\([0-9]1,3)(.*)", m))
str := m1 json("__chrA:" m2) m3
return regexreplace(str, "\\\\", "\")
str := [], obj := []
while (RegExMatch(i, "s)^(.*?[^\\])""((\\""|[^""])*?[^\\]|)""(.*)$", m))
str.insert(json("__str:" m2)), i := m1 "__str<" str.maxIndex() ">" m4
while (RegExMatch(RegExReplace(i, "\s+", ""), "s)^(.*?)(\|\[)([^\\[\]\]*?)(\|\])(.*)$", m))
a := (m2="") ? 0 : 1, c := m3, i := m1 "__obj<" ((obj.maxIndex()+1) ? obj.maxIndex()+1 : 1) ">" m5, tmp := []
while (RegExMatch(c, "^(.*?),(.*)$", m))
tmp.insert(m1), c := m2
tmp.insert(c), tmp2 := , obj.insert(cobj := )
for k,v in tmp
if (RegExMatch(v, "^(.*?):(.*)$", m))
tmp2[m1] := m2
else
tmp2.insert(v)
for k,v in tmp2
for x,y in str
k := RegExReplace(k, "__str<" x ">", y), v := RegExReplace(v, "__str<" x ">", y)
for x,y in obj
v := RegExMatch(v, "^__obj<" x ">$") ? y : v
cobj[k] := v
return obj[obj.maxIndex()]
source
【讨论】:
以上是关于使用 AutoHotkey 解析、生成和美化/格式化 Json?的主要内容,如果未能解决你的问题,请参考以下文章