【问题标题】:Search for blocks of consecutive lines matching a pattern in Vim在 Vim 中搜索匹配模式的连续行块
【发布时间】:2020-08-06 05:51:04
【问题描述】:

我想知道在 Vim 中是否有某种方法可以通过 block 浏览搜索结果,其中 block 是一段行,每行都有一个搜索模式。

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

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 行,依此类推。它应该忽略连续行中发生的匹配(即,在一个块内)并跳转到下一个块。

【问题讨论】:

    标签: search vim


    【解决方案1】:

    你可以折叠吗?

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

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

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

    • zM - 关闭所有折叠
    • zR - 打开所有折叠
    • zj下移一折,zk上移一折

    • zcdd 将当前块拉入默认寄存器

    【讨论】:

      【解决方案2】:

      马上,我不记得 vim 是否具有进行多行匹配的能力。如果是这样,您可以在搜索模式中指定换行符。在 Perl 中,这看起来像这样(我很快就将它搞定了,没有查找多行正则表达式,所以我可能有一些语法错误,但它足够接近作为示例)。

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

      这将查找“模式”,然后是 4 行可能包含或不包含“模式”的行。

      这样做的问题是,如果你有两个重叠的块,我认为这个搜索会混淆。

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

      使用 +q+ 定义宏,然后使用 +@+ 执行。因此,对于您的“搜索模式块”示例,使用 't' as ,您将执行以下操作:

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

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

      【讨论】:

        【解决方案3】:

        可以使用两种不同的策略来翻译您的定义 Vim 正则表达式中的一个块。首先,它可以设计成匹配 块的第一行,即与模式匹配但 前面没有匹配相同模式的行。

        /\%(\1\n\)\@<!\(pattern\)
        

        其次,可以搜索后面几行,全部匹配 模式,但是,为了跳过整个块来找到下一个 出现时,光标放在匹配块的末尾。

        /\(pattern\)\%(\n\1\)*/e
        

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

        【讨论】:

          猜你喜欢
          • 2013-08-13
          • 2017-05-27
          • 2016-04-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-03-12
          相关资源
          最近更新 更多