Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delete anything other than pattern

Tags:

vim

search

Let's say this is my text:

this is my text this
is my text this is my text
my text is this

I would like to highlight all text except pattern and delete the highlighted text.
p.e. text: this must be the result.

text
texttext
text

I've found the code how to select all text except pattern:
\%(\%(.{-}\)\@!text\zs\)*

however I don't know how to delete all highlighted text.
This doesn't work:
:%s/\%(\%(.{-}\)\@!bell\zs\)*//

Can anyone help me?

like image 693
Reman Avatar asked Jun 06 '11 07:06

Reman


3 Answers

Try this:

:%s/\(^\|\(text\)\@<=\).\{-}\($\|text\)\@=//g

Explanation:

\(^\|\(text\)\@<=\)     # means start of line, or some point preceded by “text”
.\{-}                   # as few characters as possible
\($\|text\)\@=          # without globbing characters, checking that we reached either end of line or occurrence of “text”.

Another way to do it:

  • Create a function that count matches of a pattern in a string (see :help match() to help you design that)
  • Use: :%s/.*/\=repeat('text', matchcount('text', submatch(0)))
like image 119
Benoit Avatar answered Oct 23 '22 21:10

Benoit


Forgive me, because I'm not a vim expert, but wouldn't prepending the search with v find the inverse so that you could do something like this?

:v/pattern/d
like image 40
Chuck Avatar answered Oct 23 '22 19:10

Chuck


I've implemented Benoit's clever regular expression as a custom :DeleteExcept command in my PatternsOnText plugin. It offers other related commands like :SubstituteExcept or :SubstituteInSearch, too.

OP's example would be

:%DeleteExcept /text/

Comparing that with @Benoit's explicit command (:%s/\(^\|\(text\)\@<=\).\{-}\($\|text\)\@=//g), it's a lot simpler.

like image 5
Ingo Karkat Avatar answered Oct 23 '22 20:10

Ingo Karkat