【问题标题】:Regex / Vim: Matching everything except a pattern, where pattern is multi-line?Regex / Vim:匹配除模式之外的所有内容,其中模式是多行的?
【发布时间】:2012-03-06 00:48:22
【问题描述】:

Vim 中是否有办法执行与

类似的操作
:v/PATTERN/d 

PATTERN 是一个多行正则表达式模式?我确信有一种方法可以在脚本中执行此操作,但我主要好奇是否可以仅使用标准正则表达式替换或 Vim 命令来执行此操作,因为此时它比实际需要更具学术性。

我的例子如下:

asdf

begin
   blah
end

asdf

alsdfjasf

begin
   random stuff
end
...

我想用它们之间的线来获取开始/结束的块,但忽略块之外的所有内容,最终以

结尾
begin
   blah
end

begin
   random stuff
end
...

我的想法是这样做

:v/begin\_.\{-}end/d 

所有不匹配的内容都将被删除甚至复制以进行注册,但显然 :v 和 :g 仅适用于单行。

然后,我开始走下运行替代的道路,并用与begin\_.\{-}end 模式不匹配的空字符串替换所有内容,但我无法掌握如何使用后视或任何东西来实现这一点。正则表达式在搜索时工作得非常好,但我不知道如何告诉正则表达式引擎找到除该模式之外的所有内容。有什么想法吗?

【问题讨论】:

    标签: regex vim


    【解决方案1】:

    g 和 v 执行的命令本身可以采用范围,因此您可以使用 :g /begin/ .,/end/xxx 对从“开始”到“结束”的所有内容执行操作,其中 xxx 是要在该范围内执行的命令。您不能真正将其用于:v,但您可以通过多种方式多次通过,例如

    "mark all the lines we want to keep by putting '@' at the start of the line"
    :g/^begin/ .,/^end/  s/^/@/
    "delete all unmarked lines"
    :v/^@/ d
    "remove the markers"
    :s/^@//
    

    当然,这假设您在文件中没有任何以@开头的行。

    或者,您可以删除每个“结束”和下一个“开始”之间的所有内容

    :g/^end/ +1,/^begin/-1 d
    

    然后删除文件开头和结尾的剩余部分:

    :1,/^begin/-1 d
    :$?^end?+1,$ d
    

    注意使用$?^end?+1从文件末尾向后搜索以找到以“end”开头的最后一行。

    注意如果文件以“begin”开头或以“end”结尾,最后两个将删除太多,因此在使用它们之前请检查。

    【讨论】:

      【解决方案2】:

      将其翻过来,并删除所有由模式分隔的内容:

      :%s/\%(^end\n*\|\%^\)\zs\_.\{-}\ze\%(^begin\|\%$\)//
      
      • \%( ... ) - 非捕获组
      • ^end\n* - 模式结束
      • \%^ - 文件开头
      • \zs - 不要在要替换的字符串中包含此点之前匹配的任何内容
      • \_.\{-} - 任何东西的非贪婪匹配(包括换行符)
      • \ze - 不要在要替换的字符串中包含此点之后匹配的任何内容
      • ^begin - 模式的开始
      • \%$ - 模式结束

      【讨论】:

      • 太棒了!我想将此标记为答案,但我已经将第一个响应(来自 kev)标记为答案,删除它我会感到难过。从技术上讲,他们都回答了我的问题,但我认为这个回答了我关于替换 :v/pattern/d 的原始问题。
      【解决方案3】:

      清除注册a

      qaq
      

      begin...end 附加到注册a

      :g/begin/,/end/y A
      

      打开新标签

      :tabnew
      

      把注册a

      "ap
      

      【讨论】:

      • 出色且绝对快速的响应。让我吃惊的是,你每天可以使用 Vim 多长时间并学习新东西。
      猜你喜欢
      • 1970-01-01
      • 2019-10-14
      • 1970-01-01
      • 2014-01-30
      • 1970-01-01
      • 2021-05-26
      • 2022-08-21
      相关资源
      最近更新 更多