簡體   English   中英

正則表達式/ Vim:匹配除模式之外的所有內容,其中模式是多行的?

[英]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

把REG 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM