Vimgrep 在任何空行之前

Vimgrep before any empty line

我有很多文件以我定义的一些标签开头。

示例:

=Title
@context
!todo
#topic
#subject
#etc

And some text (notice the blank line just before this text).

Foo
Bar

我想写一个 Vim 搜索命令(使用 vimgrep)来匹配空行之前的内容。

如何只在第一个空行之前的行中进行 grep?它会使 grep 动作更快吗?请不要提及 :grep 和二进制 Ag - silver search.

我知道 \_.* 匹配所有内容,包括 EOL。我知道否定 [^foo]。我成功地用 /[^^$] 匹配除了空行之外的所有内容。但是我没有设法编写我的 :vimgrep 命令。感谢您的帮助!

[...] 总是匹配单个字符。 [^^$] 匹配一个非 ^$ 的字符。这不是你想要的。


您可以做的事情之一是:

/\%^\%(.\+\n\)\{-}.\{-}\zsfoo/

这匹配

  • \%^ - 文件开头
  • \%( \) - 一个non-capturing组
  • \{-} - ...重复0次或更多次(越少越好)
  • .\+ - 1 个或更多 non-newline 个字符
  • \n - 一个换行符
  • .\{-} - 0 个或更多 non-newline 个字符(尽可能少)
  • \zs - 比赛正式开始

这将找到第一次出现的 foo,从文件的开头开始,仅搜索 non-empty 行。但仅此而已:您不能使用它来查找多个匹配项。


或者:

/\%(^\n\_.*\)\@<!foo/
  • \%( \) - 一个non-capturing组
  • \@<! - not-preceded-by 修饰符
  • ^ - 行首
  • \n - 换行符
  • \_.* - 0 个或多个任意字符

这匹配每一次出现的 foo 之前没有任何空行(即 beginning-of-line / 换行符组合)。

如果你想要一个通用解决方案,它适用于文件的任何内容让我告诉你AFAK,您不能 使用那种形式的文本。你可能会问为什么?


  • 解释:


vimgrep 需要模式参数来逐行搜索 ,其行为与 :global 命令完全相同。

对于您的情况,我们需要获取第一个空行之前的第一部分。 (可以扩展为:获取第一个非空白文本

让我们打电话:

  • A :每个文本块在

  • 中不包含任何单个空行
  • x :空行

只有这些 5 形式的内容文件你可以得到第一个 A 块vimgrep(情况 2,4,5 很明显):

1 | 2 | 3 | 4 | 5


x | x | A | x | A

A | A | x | A | x

x | x | A

A |

查看您的文件,其格式如下:

A

x

A

x

A

中间的块会导致问题,这就是为什么你不能拆分第一个 A 除非你用一些已知的唯一文本分隔它.


所以我能为仅有的 5 个案例 提出的唯一解决方案 是:

:vimgrep /\_.\{-}\(\(\n\s*\n\)\+\)\@=/ %

据我所知,使用 :vimgrep 最多可以使用 \%<XXl 原子在特定行号下方搜索:

:vim /\%<20lfunction/ *.vim

该命令将在给定文件中的第 20 行上方找到 function 的所有实例。

:help \%l