【问题标题】:Vim: delete until character for all lines containing a patternVim:删除包含模式的所有行的直到字符
【发布时间】:2012-07-12 21:04:52
【问题描述】:

我正在学习 power of g 并想删除所有包含表达式的行,直到句子的末尾(用句号标记)。像这样:

There was a little sheep. The sheep was black. There was another sheep.

(运行命令查找所有类似There was的句子并删除到下一个句号。

The sheep was black.

我试过了:

  1. :g/There was/d\/\. 试图“删除到下一个期间”,但我收到 trailing characters 错误。
  2. :g/There was/df. 但得到一个df. is not an editor command error.

有什么想法吗?

【问题讨论】:

    标签: vim


    【解决方案1】:

    g 关联的操作必须能够在不需要来自g 所暗示的模式匹配的位置信息的情况下对该行进行操作。在您使用的命令中,delete forward 命令需要一个未提供的起始位置。

    问题在于g 仅表示行匹配,而不是模式匹配的特定字符位置。我做了以下事情,它做了我认为你想要的:

    :g/There was/s/There was[^.]*[.]//
    

    这找到了与模式There was 匹配的行,并用空字符串替换了正则表达式There was[^.]*[.]

    这相当于:

    :1,$s/There was[^.]*[.]//g
    

    我不确定g 在您的用例中为您带来了什么,除了自动应用到整个文件行范围(与1,$% 相同)。后一个示例中的 g 与将替换应用于同一行上的所有模式有关,而不是与受替换命令影响的行范围有关。

    【讨论】:

      【解决方案2】:

      我只会使用正则表达式:

      %s/There was\_.\{-}\.\s\?//ge
      

      注意\_. 如何允许跨行句子

      【讨论】:

      • 次要评论:如果他在句子之间使用两个(或更多)空格,那只会删除其中一个。虽然不知道跨线匹配。为此 +1。
      • 谢谢。你能解释为什么尝试使用:g 不起作用吗?此外,对于未来的读者:e 标志会在找不到模式时抑制错误(必须查找)。
      • 您也可以使用 g。但是,如果单行有多个可删除的句子,或者实际上是一个句子跨越多行,这就不那么自然了。
      【解决方案3】:

      你可以像这样使用:norm

      :g/There was/norm 0weldf.

      这会找到带有“There was”的行,然后执行普通命令0weldf.

      0:转到行首
      w:转到下一个单词(在本例中为“was”)
      e:转到单词末尾(因此光标打开"was" 的 's')
      l: 向右移动一个字符(所以我们不会删除任何 "was")
      df.: 删除到下一个 '.',包括在内。

      如果您想保留句点,请使用 dt. 而不是 df.

      如果你不想从行首删除而是想做句子,:%s 命令在这里可能更合适。 (例如,:%s/\(There was\)[^.]*\./\1/g%s/\(There was\)[^.]*\./\1./g,如果您想在句末保留句号。

      【讨论】:

        【解决方案4】:

        使用search and replace:

        :%s/There was[^.]*\.\s*//g
        

        【讨论】:

          最近更新 更多