在 Vim 中选择所有匹配的文本?

在 Vim 中选择所有匹配的文本?

我有一堆数据,我想将与以下正则表达式匹配的所有内容都提取到寄存器中:

/'user': '[a-Z]*'

有没有办法将所有匹配项复制到 vanilla vim 中的寄存器中?我看过这个问题,但它只对一个结果有效,按 'n' 转到下一个结果后,它会再次使用 '//e' 并转到下一个结果的末尾,而不是开头。

我也看过这个问题。这几乎就是我要找的东西,只是我不知道如何改变它,使它能与特定的匹配项一起工作,而不是与它们所在的行一起工作。

答案1

这可以简单地实现,通过运行设置了标志:s的命令n(基本上说,不替换任何内容(但通过\=在替换部分使用,您仍然可以捕获匹配项(参见:h sub-replace-special)。所以首先让我们清除寄存器 A:

qaq

然后,您可以使用以下命令将您的 maches 捕获到寄存器 a 中:

:%s/'user': '[a-Z]*'/\=setreg('A', submatch(0), 'V')/gn

并粘贴您的匹配项:

:put A

这至少需要 Vim 7.4(我忘记了实际的补丁号)。

答案2

“清除‘a’寄存器

qaq

“全局搜索并将所有行(‘A’)放入‘a’寄存器中。

:g/'user': '[a-Z]*'/y A

:g/ and /y A根据需要修改之间的部分。

“粘贴到另一个文件中

"aP

答案3

您可以使用:YankMatches我的命令ExtractMatches 插件

:%YankMatches /'user': '[a-Z]*'/

默认情况下,每个匹配项都放在新行上;要使用其他分隔符,可以使用替代形式。

答案4

可能还有更好的方法(如果我们讨论的是大量条目,这些方法效率很低——只要不是成千上万,应该没问题),但我首先想到的是递归宏。首先,关闭 wrapscan 选项,这样到达文件末尾的搜索就不会再次循环到开头(否则您将陷入无限循环):

:set nowrapscan

然后,确保您有两个清晰的寄存器:

qqq
qaq

现在,魔术来了:

qq/'user': '[a-Z]*'
"Ay//e
@qq

qq开始将所有击键记录到寄存器中q。使用大写字母会使 vim 追加到该寄存器而不是覆盖它。y//e拉到搜索的末尾。 @q将(当前为空的)寄存器q调用为宏,最后一个q停止记录。然后,只需:

@q

相关内容