将Vimscript字典导出为JSON
我发现了一个插件,可以让Vim解析JSON。我需要将VimScript字典导出为JSON。目前我正在使用:将Vimscript字典导出为JSON,json,vim,Json,Vim,我发现了一个插件,可以让Vim解析JSON。我需要将VimScript字典导出为JSON。目前我正在使用: let str = string(dict) substitute(str, "'", '"', 'g') 这是可行的,但当我遇到带有嵌入引号的词典时,它肯定会崩溃。有什么更好的方法吗?我为echojson字符串编写了一个小函数,用“双引号转义。不确定它是否适合您的需要: function! ToJson(input) if type(a:input) == type({})
let str = string(dict)
substitute(str, "'", '"', 'g')
这是可行的,但当我遇到带有嵌入引号的词典时,它肯定会崩溃。有什么更好的方法吗?我为
echo
json字符串编写了一个小函数,用“
双引号转义。不确定它是否适合您的需要:
function! ToJson(input)
if type(a:input) == type({})
echo "{"
let di = 0
for key in keys(a:input)
let di += 1
if type(key) == type('')
echo '"'.substitute(key, '"', '\\"','g').'":'
else
echo '"'.key.'":'
endif
call ToJson(a:input[key])
echo di<len(a:input)? "," : ""
endfor
echo "}"
elseif type(a:input) == type([])
echo "["
let li = 0
for e in a:input
let li += 1
call ToJson(e)
if li<len(a:input)
echo ","
endif
endfor
echo "]"
elseif type(a:input) == type('')
echo '"'.substitute(a:input, '"', '\\"','g').'"'
else
echo '"'.a:input.'"'
endif
endfunction
将输出为:
{
"four":
"''"
,
"one":
"\"\"\""
,
"two":
"123"
,
"333":
[
"11"
,
"22"
,
"\"_\"_\""
]
}
我没有做太多的调试/测试。而且格式看起来不太好,但我猜您不在乎格式,因为您使用了string()
上述输出可以格式化为(通过在线json格式化程序):
希望有帮助。我不确定这是否应该是一个单独的答案、对@Kent答案的编辑,还是对@Kent答案的评论。下面是@Kent函数的一个版本,有一些简化:
function! ToJson(input)
let json = ''
if type(a:input) == type({})
let json .= "{"
let di = 0
for key in keys(a:input)
let di += 1
let json .= '"'.escape(key, '"').'":'
let json .= ToJson(a:input[key])
let json .= di<len(a:input)? "," : ""
endfor
let json .= "}"
elseif type(a:input) == type([])
let json .= "["
let li = 0
for e in a:input
let li += 1
let json .= ToJson(e)
if li<len(a:input)
let json .= ","
endif
endfor
let json .= "]"
else
let json .= '"'.escape(a:input, '"').'"'
endif
return json
endfunction
使用这两个版本,除了空格外,我得到的结果与@Kent的函数相同。我没有用比@Kent的d1
更复杂的东西对它进行过测试。从Vim 7.4.1304开始使用deepcopy()
可能比copy()
更安全(Vim 8.0绝对可用),这些功能内置于Vim as和中
为了向后兼容更旧的Vim版本,该插件使用纯Vimscript实现了JSON解析器和编码器:
:let jsonString = webapi#json#encode({...})
基于@benjifisher的回答,我进化出了
ToJson
缩进是有问题的,但大部分是有效的
“检查变量
"
“输入:变量
“级别:嵌套的实际级别
“max:nest let json的最大级别=”
功能!ToJson(输入、级别、最大值)
如果a:电平0
让funcName='{.dictFunc.'}'
其他的
设funcName=a:input
恩迪夫
让json.escape(genutils#ExtractFuncListing(funcName,0,0),“”)。“\”
其他的
让json.=''''''.escape(a:input''''')。"\""
恩迪夫
其他的
尝试
让json。转义(字符串(a:输入),“”)。“\”
抓住
“string()可能抛出E724(嵌套太多)
让json。转义(键(a:输入),“”)。“\”
末日
恩迪夫
返回json
端功能
要显示函数定义,您需要依赖于:
如果这一部分不适用于您,应该在visual vim调试器上使用它来检查复杂变量,请忽略这一部分。在我最初的答案发布两年半后,有一个更简单的选择:升级到vim 8并使用
json_encode()
或(如果您不需要严格的json)js_encode()
什么插件?那么,JSON到Vim插件不走另一条路有什么意义呢?+1您的答案。我也在尝试使用escape()
,但是我可能会犯一些愚蠢的错误,在输出中没有斜杠。我没有进一步测试,而是使用了sub..()
。同样对于map,我也想到了它,但是我需要在每个递归步骤中deepcopy
对象,我认为如果dict有相对更多的嵌套级别,可能会有一些问题。但我没有仔细考虑。
function! ToJson(input)
let json = ''
if type(a:input) == type({})
let json .= "{"
let di = 0
for key in keys(a:input)
let di += 1
let json .= '"'.escape(key, '"').'":'
let json .= ToJson(a:input[key])
let json .= di<len(a:input)? "," : ""
endfor
let json .= "}"
elseif type(a:input) == type([])
let json .= "["
let li = 0
for e in a:input
let li += 1
let json .= ToJson(e)
if li<len(a:input)
let json .= ","
endif
endfor
let json .= "]"
else
let json .= '"'.escape(a:input, '"').'"'
endif
return json
endfunction
function! ToJson(input)
let json = ''
if type(a:input) == type({})
let parts = copy(a:input)
call map(parts, '"\"" . escape(v:key, "\"") . "\":" . ToJson(v:val)')
let json .= "{" . join(values(parts), ",") . "}"
elseif type(a:input) == type([])
let parts = map(copy(a:input), 'ToJson(v:val)')
let json .= "[" . join(parts, ",") . "]"
else
let json .= '"'.escape(a:input, '"').'"'
endif
return json
endfunction
:let jsonString = webapi#json#encode({...})