Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将Vimscript字典导出为JSON_Json_Vim - Fatal编程技术网

将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({})

我发现了一个插件,可以让Vim解析JSON。我需要将VimScript字典导出为JSON。目前我正在使用:

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({...})