如何使用Vim提取正则表达式匹配 [英] How to extract regex matches using Vim

查看:469
本文介绍了如何使用Vim提取正则表达式匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个例子:

case Foo:
    ...
    break;
case Bar:
    ...
    break;
case More: case Complex:
    ...
    break:
...

我想检索所有正则表达式case \([^:]*\):的正则表达式匹配项(整个匹配文本,甚至更好的是\(\)之间的部分),它应提供(在新的新缓冲区中) )之类的

I’d like to retrieve all the regex matches (the whole matching text, or even better, the part between \( and \)) of the regex case \([^:]*\):, which should give (in a new new buffer) something like

Foo
Bar
More
Complex
...

用例的另一个示例是某些部分的提取,例如,从HTML文件提取图像的URL.

Another example of use case would be the extraction of some parts, for instance, URLs of images from an HTML file.

有没有一种简单的方法可以绘制所有正则表达式匹配的图形并将其放在Vim的缓冲区中?

Is there a simple way to graph all regex matches and put them in a buffer in Vim?

注意:它类似于问题使用vim提取文本,但是我对此感兴趣同样,最好在没有巨大或复杂的正则表达式的情况下删除不匹配的行.

Note: It’s similar to the question extract text using vim, however I’m interested also in removing the lines that don’t match preferably without a huge or complex regex.

推荐答案

有一种通用的方式来收集整个片段中的模式匹配项 文字.该技术利用替代品的优势 :substitute命令的表达式功能 (请参见:help sub-replace-\=).关键思想是使用替代 枚举所有模式匹配以评估表达式存储 他们没有替换.

There is a general way of collecting pattern matches throughout a piece of text. The technique takes advantage of the substitute with an expression feature of the :substitute command (see :help sub-replace-\=). The key idea is to use a substitution enumerating all of the pattern matches to evaluate an expression storing them without replacement.

首先,让我们考虑保存比赛.为了保持顺序 匹配的文本片段,使用列表很方便 (请参见:help List).但是,无法修改列表 直接使用:let命令,因为没有办法 在表达式(包括\=替换表达式)中运行Ex命令. 但是,我们可以调用其中一个在适当位置修改列表的函数.为了 例如,add()函数旨在将给定项目附加到 指定的列表(请参见:help add()).

First, let us consider saving the matches. In order to keep a sequence of matching text fragments, it is convenient to use a list (see :help List). However, it is not possible to modify a list straightforwardly, using the :let command, since there is no way to run Ex commands in expressions (including \= substitute expressions). Yet, we can call one of the functions that modify a list in place. For example, the add() function is designed to append a given item to the specified list (see :help add()).

另一个问题是如何避免在运行时修改文本 替代.一种方法是使模式始终具有 通过在\ze前面添加或在其上附加\zs原子来实现零宽度匹配 (请参见:help /\zs:help /\ze).以这种方式修改的图案 捕获在发生之前或之后的空字符串 文本中的原始模式(此类匹配称为零宽匹配 在Vim中;参见:help /zero-width).然后,如果替换文字也是 空的,替换实际上不会改变任何东西:它只是替换 带有空字符串的零宽度匹配.

Another problem is how to avoid text modifications while running a substitution. One approach is to make the pattern always have a zero-width match by prepending \ze or by appending \zs atoms to it (see :help /\zs, :help /\ze). The pattern modified in this way captures an empty string preceding or succeeding an occurrence of the original pattern in text (such matches are called zero-width matches in Vim; see :help /zero-width). Then, if the replacement text is also empty, substitution effectively changes nothing: it just replaces a zero-width match with an empty string.

由于add()功能以及大部分列表修改 函数,返回对已更改列表的引用(对于我们的技术) 要工作,我们需要以某种方式从中获取一个空字符串.最简单的 方法是通过指定范围从中提取长度为零的子列表 索引,以使开始索引大于结束索引.

Since the add() function, as well as the most of the list modifying functions, returns the reference to the changed list, for our technique to work, we need to somehow get an empty string from it. The simplest way is to extract a sublist of zero length from it by specifying a range of indices such that a starting index is greater than an ending one.

结合上述思想,我们获得以下Ex命令.

Combining the aforementioned ideas, we obtain the following Ex command.

:let t=[] | %s/\<case\s\+\(\w\+\):\zs/\=add(t,submatch(1))[1:0]/g

执行后,将累积第一个子组的所有匹配项 在变量t引用的列表中,可以按原样使用,也可以使用 以某种方式处理.例如,粘贴列表一的内容 在插入模式下,在单独的行上按一个,然后键入

After its execution, all matches of the first subgroup are accumulated in the list referenced by the variable t, and can be used as is or processed in some way. For instance, to paste contents of the list one by one on separate lines in Insert mode, type

Ctrl + R =t Enter

要在普通模式下执行相同操作,只需使用:put命令:

To do the same in Normal mode, simply use the :put command:

:pu=t

这篇关于如何使用Vim提取正则表达式匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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