在Vim中搜索与模式匹配的连续行块

4

我想知道在Vim中是否有一种方法可以按块浏览搜索结果,其中一个块是一系列具有搜索模式出现的行。

比如说,缓冲区的内容如下:

Line 1: Pattern
Line 2: Pattern
Line 3: Pattern
Line 4: 
Line 5: Pattern
---- No Pattern here ----
Line n+1: Pattern
Line n+2: 
Line n+3: 
Line n+4: Pattern
Line n+5: Pattern

然后,该命令应从第1行导航到第5行、第n+1行、第n+4行等。它应忽略在连续行(即在块内)发生的匹配,并跳转到下一个块。

3个回答

1

你可以使用折叠来实现。

折叠连续包含最后搜索模式的代码块:

:se fdm=expr foldenable foldexpr=getline(v:lnum)=~@/

现在你可以使用常规的折叠导航

  • zM - 关闭所有折叠
  • zR - 展开所有折叠
  • zj 向下移动一个折叠,zk 向上移动一个折叠

  • zcdd 把当前区块拷贝到默认寄存器中


0

我一时想不起来vim是否具有多行匹配的能力。如果有的话,您可以在搜索模式中指定换行符。在Perl中,这看起来像这样(我很快地编写了这个示例,没有查找多行正则表达式,所以语法可能有些错误,但足以作为一个例子)。

/(pattern)(\n(pattern)*){4}/m

这将寻找“pattern”,然后是可能包含或不包含“pattern”的4行。

问题在于,如果你有两个重叠的块,我认为这种搜索方法会变得混乱。

你可以做的另一件事是定义一个vim宏,它会搜索,然后向下移动5行。

宏是用+q+定义的,然后使用+@+执行。因此,对于您的“搜索pattern块”示例,使用“t”作为,你可以像这样做:

<esc>qt   # start macro 't' 
/pattern  # search for 'pattern'
5j        # move down 5 lines
<esc>q    # end macro

然后,您将从文档顶部开始,重复按“@t”


0
一个人可以使用两种不同的策略来将你对代码块的定义翻译成 Vim 正则表达式。首先,它可以被设计为匹配代码块的第一行,即与该模式匹配但前面没有与相同模式匹配的行。
/\%(\1\n\)\@<!\(pattern\)

其次,可以搜索匹配模式的多个连续行,但是为了跳过整个块以查找下一个出现的位置,光标会放在匹配的块末尾。
/\(pattern\)\%(\n\1\)*/e

就我个人而言,我更喜欢前一种解决方案。


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