views:

171

answers:

4

Using Vim, I'd like to be able to replace preVARIABLETEXTpost with VARIABLETEXT in a single command. The reason is that pre and post might exist elsewhere in the file, and VARIABLETEXT changes.

Something like:

:%s/preGRABTEXTpost/GRABTEXT/g

Essentially I'm trying to strip pre and post when it exists with some text between them on a single line, though it might exist more once on a single line. I just don't know how to make something like a temporary variable . . . help? Thanks for your time.

A: 

The . regex operator means "anything". The + means "at least once, but possibly more". Therefore:

:%s/pre(.+)post/\1/g

This will, unfortunately, match this as one group:

preGRABTEXTpostMORETEXTwibbleEVENMORETEXTpost

To fix that, we make it lazy by using the ? operator:

:%s/pre(.+?)post/\1/g

The parentheses tell vim to select that portion as a group and number it. As we only have one group, it's numbered 1. We then use \1 in the replacement to signify we want to use it. This should do it.

Samir Talwar
In VIM there the lazy `+` does not go like `+?`, but like `\{-1,\}`
Tomalak
Damnit, forgot about that. Thanks for the reminder.
Samir Talwar
+2  A: 
:%s/\v<pre(.{-1,})post>/\1/g

could work, depending a bit on your input. For me, it changes:

preAApost preBBpost
preCCpost preDDpost
preEEpost
prepost

to:

AA BB
CC DD
EE
prepost
Tomalak
A: 

Edited : :%s/pre(.{-})post/\1/g

does the trick

Lliane
No, it does not. It fails for the "multiple per line" case.
Tomalak
:%s/pre\(.\{-}\)post/\1/g
Lliane
A: 

If you are looking to do this for a particular variable, say the one under your cursor, you can map a command. For instance:

:map mm eb"aywo<esc>^Di:%s/pre<ESC>"apapost/<ESC>"apa/g<ESC>"zdd@z

Would map the key combination 'mm' to search for the text under your cursor surrounded by pre and post. Helpful if you've got several variables existing between pre/post text and only want to get rid of a particular one.

ezpz