[英]Regex / Vim: Matching everything except a pattern, where pattern is multi-line?
在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
模式不匹配,但我無法掌握如何使用look-behinds或任何東西來實現。 正則搜索時正則表達式完全正常,但我無法弄清楚如何告訴正則表達式引擎找到所有內容但該模式。 有任何想法嗎?
a
qaq
begin...end
以章第a
:g/begin/,/end/y A
:tabnew
a
"ap
將其翻轉出來,並刪除模式分隔的所有內容:
:%s/\%(^end\n*\|\%^\)\zs\_.\{-}\ze\%(^begin\|\%$\)//
\\%( ... )
- 非捕獲組 ^end\\n*
- 模式的結束 \\%^
- 文件的開頭 \\zs
- 在要替換的字符串中不包括此點之前匹配的任何內容 \\_.\\{-}
- 任何事物的非貪婪匹配(包括換行符) \\ze
- 不要在要替換的字符串中包含此點之后匹配的任何內容 ^begin
- 你的模式的開始 \\%$
- 模式的結束 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”結束,則最后兩個將刪除太多,因此請在使用之前進行檢查。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.