Vim:使用正则表达式中的\_.跨多行匹配字符串时,:yank命令仅适用于第一行。

7
我希望提取跨越多行的文本的多个出现次数,并使用单个Vim正则表达式(使用元字符\_)进行匹配。 不幸的是,尽管匹配行在Vim中正确地高亮显示, 但当我在匹配正则表达式后添加任何Vim命令(如删除或复制)时, 该命令仅适用于每个匹配的第一行。 示例:
 1: bad_function(arg1,  
 2:              arg2, arg3,
 3:              ...
 4:              argN);
 5: good_function();
 6: ...
 7: bad_function(arg2_1,
 8:              ...
 9:              arg2_N);
10: another_good_function();  

如果我执行:g/bad_function([^;]\+\_[^;]\+;$/d,那么只有第1行和第7行被删除,尽管高亮显示的是第1-4行和第7-9行。
如何复制/删除所有匹配(高亮)的行?

相关的吗?https://dev59.com/dXM_5IYBdhLWcg3wNwQv - Sanjay T. Sharma
3个回答

6

试试这个:

:let @a=''
:g/first\_.*second.*$/normal! v/second^M$"Ay

使用CTRL-V键输入^M,然后按Enter。


这似乎有点复杂,为什么不直接使用 :%g/first.*\|second.*/yank z 呢? - Sanjay T. Sharma
因为这不会拉取中间行。 - Benoit
的确,OP最初的意图不是很清晰,我看到问题已经被修改得更加明确了。 - Sanjay T. Sharma

1
为了在寄存器中累积匹配行的范围,可以使用以下命令。
:let @a='' | g/^first/,/^second/y A

如果是这样,为什么我的 :%g/first\_.*second.*$/'<,'>y 能够工作呢? - Chris Morgan
@Chris 这个工作是因为你明确指定了要复制的行范围(顺便说一下,这个范围恰好等于匹配范围,这只是巧合,请参见我对你答案的评论)。 - ib.

0

正如我在评论中指出的那样,链接的问题已经提供了解决方案:

:%g/your_pattern/yank A
P

对我来说可行。

如果你想在不同的行上匹配多个术语,你可以尝试(在命令模式下):

"zyy (do this on empty line to empty the register 'z')
:%g/first.*\|second.*/yank z (grab matches in the 'z' register)
P (for pasting the contents of the last register)

它仍然无法工作,只有第一行被复制。我在上面添加了一个示例。 - tombkeeper
但是,如果第一行和第二行之间没有特定模式的某些行,您如何将它们拖放出来? - tombkeeper
@tombkeeper:我看到你修改了你在问题中发布的例子,因为之前你表述的方式不太清晰。 - Sanjay T. Sharma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接