迭代Vimscript中的字符串或解析JSON文件

迭代Vimscript中的字符串或解析JSON文件,json,string,parsing,vim,Json,String,Parsing,Vim,因此,我正在创建一个vim脚本,它需要将JSON文件加载并解析到本地对象图中。我搜索了,但找不到任何本机方式来处理JSON文件,我不想向脚本添加任何依赖项。因此,我编写了自己的函数来解析JSON字符串(从文件中获取),但速度非常慢。目前,我遍历文件中的每个字符,如下所示: let len = strlen(jsonString) - 1 let i = 0 while i < len let c = strpart(jsonString, i, 1) let i += 1

因此,我正在创建一个vim脚本,它需要将JSON文件加载并解析到本地对象图中。我搜索了,但找不到任何本机方式来处理JSON文件,我不想向脚本添加任何依赖项。因此,我编写了自己的函数来解析JSON字符串(从文件中获取),但速度非常慢。目前,我遍历文件中的每个字符,如下所示:

let len = strlen(jsonString) - 1
let i = 0
while i < len
    let c = strpart(jsonString, i, 1)
    let i += 1
    " A lot of code to process file....
    " Note: I've tried short cutting the process by searching for enclosing double-quotes when I come across the initial double quotes (also taking into account escaping '\' character.  It doesn't help
endwhile
作为参考,处理一个约29000个字符的文件大约需要4秒钟,这是不可接受的

在vim脚本中有更好的方法来迭代字符串吗

或者更好的是,我是否错过了解析JSON的本机函数

更新: 我要求没有依赖项,因为我:

  • 我不想和他们打交道
  • 真诚地想要一些最好的方法来做到这一点,而不需要别人的工作的想法
  • 有时我只是喜欢手工操作,即使问题已经解决了 我一点也不反对插件或依赖项,只是我很好奇。这就是问题所在

    我最终创建了自己的函数来解析JSON文件。我正在创建一个脚本,可以解析与node.js模块关联的
    package.json
    文件。因此,我可以依赖一种相当一致的格式,在检索到所需信息时退出处理。这通常会删除文件中的大块,因为大多数开发人员将文件中最大的块,即他们的“自述”部分放在最后。因为
    package.json
    文件是严格定义的,所以我让这个过程有些脆弱。它假定根字典
    {}
    ,并主动查找某些条目。您可以在此处找到脚本:


    当然,这并不能回答我自己的问题。这只是我唯一问题的解决办法。我会等几天,等待新的答案,然后在悬赏结束前挑选最好的答案(我的手机上已经设置了闹钟)

    尽管Vim的起源可以追溯到很久以前,但它的内部string()eval()表示形式与JSON非常接近,除非您需要特殊字符,否则它很可能工作

    如果需要,您可以在此处查找甚至支持true/false/null的实现:

    更好地使用该库(vim插件管理器允许轻松安装依赖项)。 现在,这取决于你的数据是否足够好

    现在Benjamin Klein把你的问题发到vim_use,这就是我回答的原因。 如果你订阅了Vim邮件列表,就会得到最好、最快的回复。 转到vim.sf.net并关注社区链接。 您不能期望Vim社区能够清除堆栈溢出

    我将关键字“json”和“parsing”添加到这个小代码中,这样可以更容易地找到它


    如果这个解决方案对您不起作用,您可以尝试许多:h If_*绑定,或者编写一个外部脚本来提取您要查找的信息,或者将JSON转换为Vim的字典表示形式,可以由eval()读取正确地转义您关心的特殊字符。

    如果您寻求完全正确的解决方案,那么省略依赖项是您能做的最糟糕的事情之一。@MarcWeber提到的
    eval()
    变体是最快的变体之一,但它也有其缺点:

  • 使用我在评论中提到的方法使它不再是最快的。事实上,使用此选项后,它会使
    eval()
    的速度降低一个数量级以上(在我的测试中为0.02s vs 0.53s)
  • 它不尊重代理项对
  • 它不能用于验证您是否有正确的JSON:它接受一些不是JSON字符串的字符串(例如,
    “\”
    ),并允许使用尾随逗号
  • 它无法给出正常的错误消息。如果您使用我在第1页中提到的
    vam#VerifyIsJSON
    ,它会严重失败
  • 它无法加载像
    1e10
    这样的浮点值(vim要求数字看起来像
    1.0e10
    ,但像第一段中的1e10:note“和/或”这样的数字)
  • 。上述所有语句(第一条除外)也适用于@MarcWeber提到的
    vim addon json编码
    ,因为它使用eval。还有其他一些可能性:

  • 最快、最正确的方法是使用python:
    pyeval('json.loads(vim.eval(“varname”)))
    。不是比eval快,而是在其他可能性中最快。(在我的测试中为0.04:大约比
    eval()慢两倍)

    注意,我在这里使用
    pyeval()
    。如果您想要缺少此功能的vim版本解决方案,它将不再是最快的解决方案之一

  • 使用我的插件。与失败的
    vam#VerifyIsJSON
    相比,它的错误报告稍好一些,与
    eval()
    相比稍差一些,并且它可以正确加载浮点数。它可以用于验证字符串(它不接受
    “\”
    ),但它可以加载带有尾随逗号的列表。它不支持代理项对。它也非常慢:在我使用的测试中(它使用279702个字符长的字符串),加载需要11.59秒。不过,如果可能的话,Json.vim会尝试使用python
  • 为了获得最佳的错误报告,您可以去掉并清除YAML支持,只留下JSON(我曾经对pyyaml做过同样的事情,不过在python中:请参阅:它是pyyaml减去YAML stuff加上带标记的类)。但是这个变体比json.vim更慢,并且只有在需要错误报告的情况下才应该使用:加载相同的279702个字符长的字符串需要207秒
  • 请注意,提到的唯一一个同时满足“无依赖项”和“无python”要求的变体是
    eval()
    。如果你对它的缺点不满意,你必须放弃其中一个或两个要求。或复制粘贴代码。不过,如果考虑到速度,只剩下两个候选者:
    eval()
    和python:如果您想快速解析json,您需要
    for c in split(jsonString, '\zs')
        " Do a lot of parsing ....
    endfor
    
    let dict = json_decode(jsonString)