使用 Vim,您如何使用变量来存储找到的模式计数? [英] Using Vim, how do you use a variable to store count of patterns found?

查看:20
本文介绍了使用 Vim,您如何使用变量来存储找到的模式计数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题 "gVim find/代替with counter",我提出了一个简单的技巧来克服这个限制,这是基于使用单个项目列表(或包含单个项目的字典)键值对).由于 map() 函数转换列表或字典就地,在受约束的表达式上下文中只能更改该项目.要做到这一点,应该调用传递表达式的 map() 函数计算新值以及包含当前值的列表.

技巧的后半部分是如何避免在使用时改变文本一个替换命令.为了实现这一点,可以制作图案通过在前面加上 \ze 或附加 \zs 原子来使宽度为零(参见:help/\zs, :help/\ze).这样,修改后的模式捕获在初始出现之前或之后的零宽度字符串图案.因此,如果替换文本也为空,则替换不会导致缓冲区内容发生任何变化.做替代品表达式计算为空字符串,可以只提取一个空字符串该表达式的结果值中的子字符串或子列表.

下面的命令将这两个想法付诸实践.

:let n=[0] |bufdo %s/pattern\zs/\=map(n,'v:val+1')[1:]/ge

This question was helpful for getting a count of a certain pattern in Vim, but it would be useful to me to store the count and sum the results so I can echo a concise summary.

I'm teaching a class on basic HTML to some high schoolers, and I'm using this script to be quickly check numbers of required elements throughout all their pages without leaving Vim. It works fine, but when students have more than 10 .html files it gets cumbersome to add up the various sections by hand.

Something like:

img_sum = :bufdo %s/<img>//gen

would be nice. I think I'll write a ruby script to check the pages more thoroughly and check for structure, but for now I'm curious about how to do this in Vim.

解决方案

The problem can be solved by a counter separate from the one built-in into the :substitute command: Use Vim-script variable to hold the number of pattern matches. A convenient way to register every match and modify a particular variable accordingly, is to take advantage of the substitute with an expression feature of the :substitute command (see :help sub-replace-\=). The idea is to use a substitution that evaluates an expression increasing a counter on every occurrence, and does not change the text it is operating on.

The first part of the technique cannot be implemented straightforwardly because it is forbidden to use Ex commands in expressions (including \= substitute expressions), and therefore it is not possible to use the :let command to modify a variable. Answering the question "gVim find/replace with counter", I have proposed a simple trick to overcome that limitation, which is based on using a single-item list (or dictionary containing a single key-value pair). Since the map() function transforms a list or a dictionary in place, that only item could be changed in a constrained expression context. To do that, one should call the map() function passing an expression evaluating to the new value along with the list containing the current value.

The second half of the technique is how to avoid changing text when using a substitution command. In order to achieve that, one can make the pattern have zero-width by prepending \ze or by appending \zs atoms to it (see :help /\zs, :help /\ze). In such a way, the modified pattern captures a string of zero width just before or after the occurrence of the initial pattern. So, if the replacement text is also empty, substitution does not cause any change in the contents of a buffer. To make the substitute expression evaluate to an empty string, one can just extract an empty substring or sublist from the resulting value of that expression.

The two ideas are put into action in the following command.

:let n=[0] | bufdo %s/pattern\zs/\=map(n,'v:val+1')[1:]/ge

这篇关于使用 Vim,您如何使用变量来存储找到的模式计数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆