Aar*_*man 6 string vim parsing json
所以我正在创建一个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
Run Code Online (Sandbox Code Playgroud)
我也尝试过这种方法:
for c in split(jsonString, '\zs')
" Do a lot of parsing ....
endfor
Run Code Online (Sandbox Code Playgroud)
作为参考,具有~29,000个字符的文件需要大约4秒来处理,这是不可接受的.
有没有更好的方法在vim脚本中迭代字符串?
或者更好的是,我是否错过了解析JSON的本机函数?
我要求没有依赖,因为我:
我根本不反对插件或依赖,只是我很好奇.这样的问题.
我最终创建了自己的函数来解析JSON文件.我正在创建一个可以解析package.json与node.js模块关联的文件的脚本.因此,我可以依赖相当一致的格式,并在我检索到所需信息时退出处理.这通常会删除文件的大块,因为大多数开发人员最后放置文件的最大块,即"自述"部分.因为package.json文件是严格定义的,所以我让这个过程有些脆弱.它假定了一个根词典{ }并主动查找某些条目.你可以在这里找到这个脚本:https://github.com/ahayman/vim-nodejs-complete/blob/master/after/ftplugin/javascript.vim#L33.
当然,这并不能回答我自己的问题.这只是我独特问题的解决方案.我会等几天寻找新的答案并在赏金结束前选择最好的答案(已经在我的手机上设置了闹钟).
小智 6
尽管 Vim 的起源可以追溯到很久以前,但它的内部 string() eval() 表示形式非常接近 JSON,除非您需要特殊字符,否则它可能会起作用。
如果需要,您可以在这里查找甚至支持 true/false/null 的实现: https: //github.com/MarcWeber/vim-addon-json-encoding
更好地使用该库(vim-addon-manager 允许轻松安装依赖项)。现在这取决于您的数据是否足够好。
现在 Benjamin Klein 将您的问题发布到 vim_use,这就是我回复的原因。如果您订阅 Vim 邮件列表,就会得到最好、快速的回复。转到 vim.sf.net 并点击社区链接。你不能指望 Vim 社区会抓取 stackoverflow。
我在这段小代码中添加了关键字“json”和“parsing”,以便更容易找到它。
如果这个解决方案不适合你,你可以尝试许多 :h if_* 绑定或编写一个外部脚本来提取你正在寻找的信息,或者将 JSON 转换为 Vim 的字典表示,可以通过 eval() 转义特殊来读取您正确关心的角色。
依赖最少的最简单的解决方案就是使用json_decodevim 函数。
let dict = json_decode(jsonString)
Run Code Online (Sandbox Code Playgroud)
如果您寻求完全正确的解决方案,那么忽略依赖项是您能做的最糟糕的事情之一。@MarcWeber 提到的变eval()体是最快的变体之一,但它有其缺点:
eval()慢一个数量级以上(在我的测试中为 0.02 秒 vs 0.53 秒)。"\\<C-o>"不是 JSON 字符串的字符串(例如 ),并且允许尾随逗号。vam#VerifyIsJSON如果你使用我在 p.1 中提到的,它会严重失败。1e10(vim 要求数字看起来像1.0e10,但允许像 1e10 这样的数字:注意第一段中的 \xe2\x80\x9cand/or\xe2\x80\x9d )。。上述所有(除了第一个)语句也适用于vim-addon-json-encoding@MarcWeber 提到的,因为它使用了 eval。还有一些其他的可能性:
最快且最正确的是使用 python: pyeval(\'json.loads(vim.eval("varname"))\')。不比 eval 快,但在其他可能性中是最快的。(在我的测试中为 0.04:大约慢两倍eval())
注意,我pyeval()这里用的是。如果您想要缺乏此功能的 vim 版本的解决方案,它将不再是最快的之一。
使用我的json.vim插件。与 failed 相比,它的错误报告稍好vam#VerifyIsJSON,与它相比稍差,eval()并且它可以正确加载浮点数。它可用于验证字符串(它不接受"\\<C-a>"),但它可以加载带有尾随逗号的列表。它不支持代理对。它也非常慢:在我使用的测试中(它使用 279702 个字符长字符串),加载需要 11.59 秒。如果可能的话,Json.vim 会尝试使用 python。
为了获得最佳的错误报告,你可以使用yaml.vim并清除 YAML 支持,只留下 JSON(我曾经对 pyyaml 做过同样的事情,尽管在 python 中:请参阅powerline 中使用的 Markedjson 库:它是 pyyaml 减去 YAML 内容加上带分数的课程)。但这个变体比 json.vim 还要慢,并且只有在您需要的主要内容是错误报告时才应该使用:加载相同的 279702 个字符长字符串需要 207 秒。
\n请注意,提到的唯一满足 \xe2\x80\x9cno dependency\xe2\x80\x9d 和 \xe2\x80\x9cno python\xe2\x80\x9d 要求的变体是eval()。如果您不能接受它的缺点,您就必须放弃其中一项或两项要求。或者复制粘贴代码。不过,如果考虑速度,就只剩下两个候选:eval()和 python:如果你想快速解析 json,你确实必须使用 C,并且只有这些解决方案将大部分时间花在用 C 编写的函数上。
大多数其他解释器(ruby/perl/TCL)没有pyeval()等效项,因此即使它们的 JSON 实现是用 C 编写的,它们也会变慢。其他一些解释器(lua/racket(mzscheme))具有pyeval()等效项,但例如luaeval(\'{}\')为零意味着您将必须显式地添加额外的步骤并递归地将对象转换为 vim 字典和列表(例如luaeval(\'vim.dict({})\')),这将影响性能。不能说什么mzeval(),但我从来没有听说过有人真正将球拍(mzscheme)与vim一起使用。