Vim中的多行正则表达式:过滤掉文件中的文本块

时间:2012-04-09 17:04:10

标签: regex vim

用于过滤以#tags结尾的多行文本块的正确正则表达式是什么?我的文件看起来像这样:

Text block 1:
- something
- something
- something
#tag1 #tag2

Text block 2:
- somethingelse
- somethingelse
#tag2

Text block 3:
- really interesting stuff
- really interesting stuff
#tag1

etc

These great tips指出我使用\_.。因此,为了过滤出包含#tag1的两个块,我提出了这个:

\_.\{-}#tag1.*

然而,这只给了我文本块1.而不是将我更多地指向文本块2(也包含标记),光标开始逐行向下移动。

我哪里错了?谢谢你的解释!


编辑:有关如何为此类查询创建多命令的后续操作是here

1 个答案:

答案 0 :(得分:3)

如果你想匹配块中的每一行(用于将匹配块中的所有文本都放入缓冲区),这对我有用。

^\(.\+\n\)\{-}#.*tag1

所以你可以做到

g/^\(.\+\n\)\{-}#.*tag1/d A

删除所有文本块(当然,如果你想把它们改为d,则改为d)以#tag1结尾并将它们拖入寄存器A,然后"ap将它们全部粘贴(或{ {1}}在插入模式下)

这让我跳转到每个块的第一行,该行以包含tag1的标签结束。

<C-r>a

的问题
\(\%^\|^\n\)\zs.\(.\+\n\)\{-}#.*tag1.*$

当你使用{ - }非贪婪时,它仍然总是匹配,只要有一行在你当前行下面有#tag1。使用_。*或_。{ - }可能非常危险。例如,当您在“文本块2:”

行时
\_.\{-}#tag1.*

在文本块3之后,您将获得整个范围文本块2的匹配,直到#tag1。

如果你有了

Text block 2:
- somethingelse
- somethingelse
#tag2

Text block 3:
- really interesting stuff
- really interesting stuff
#tag1

您只会匹配文本块3中的行。