Vim是否有办法对
执行类似的操作:v/PATTERN/d
其中PATTERN是多行正则表达式?我确信有一种方法可以在脚本中执行此操作,但我很好奇是否可以仅使用标准正则表达式替换或Vim命令,因为此时它比实际需要更具学术性。 / p>
我的例子如下:
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
模式不匹配的字符串,但我无法掌握如何使用后视或任何东西来实现。正则搜索时正则表达式完全正常,但我无法弄清楚如何告诉正则表达式引擎找到所有内容但该模式。有什么想法吗?
答案 0 :(得分:8)
a
qaq
begin...end
追加到注册a
:g/begin/,/end/y A
:tabnew
a
"ap
答案 1 :(得分:2)
将其翻转出去,并删除由模式分隔的所有内容:
:%s/\%(^end\n*\|\%^\)\zs\_.\{-}\ze\%(^begin\|\%$\)//
\%( ... )
- 非捕获组^end\n*
- 模式的结束\%^
- 文件的开头\zs
- 在要替换的字符串中不包括此前匹配的任何内容\_.\{-}
- 非贪婪匹配任何内容(包括换行符)\ze
- 请勿在要替换的字符串中包含此后匹配的内容^begin
- 模式的开头\%$
- 模式的结束答案 2 :(得分:0)
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”开头的最后一行。
N.B。如果文件以“begin”开头或以“end”结尾,则最后两个将删除太多,因此请在使用之前进行检查。