:s/pattern/replacement
operates on the first match and
:s/pattern/replacement/g
on all.
How to operate only on the last one?
Vi and Vim Stack Exchange is a question and answer site for people using the vi and Vim families of text editors. It only takes a minute to sign up.
Sign up to join this communityI would use \zs
:%s/.*\zspattern/replacement/
A little bit of explanation:
.
represents any single character*
represents greedy matching (as many as possible)In Vim you can use zero-width anchors \zs
and \ze
to define the start and the end of the searched pattern, which you wish to match. Anything before \zs
and after \ze
in your pattern will remain unaffected by replacement.
To make it easy to understand, I would like to use this example from wikia's Search and replace:
Save typing by using
\zs
and\ze
to set the start and end of a pattern. For example, instead of::s/Copyright 2007 All Rights Reserved/Copyright 2008 All Rights Reserved/
Use:
:s/Copyright \zs2007\ze All Rights Reserved/2008/
For more information, look at
\zs
does in your answer?
Oct 13, 2015 at 17:59
You can search for the last match by grouping all, \(.*\)
, but last ocurrence of pattern
. Then exiting with the captured group, \1
, and adding the replacement
.
:%s/\(.*\)pattern/\1replacement/
\zs
solution, in that your \1
approach is functionally equivalent, but more verbose. (On the other hand, it may be easier to remember for some, particularly if they are used to other regex flavors.))
Dec 30, 2016 at 1:44
For the sake of completeness I thought I'd post an alternative. Vim has multi-items some of which are similar to the more standard regular expression lookaround assertions (negative/positive lookahead/lookbehind). https://stackoverflow.com/questions/2973436/regex-lookahead-lookbehind-and-atomic-groups
In this case we want a negative lookahead, \@!
, meaning we want to assert that the atom that precedes the item does not occur after pattern. In this case the atom is the pattern itself preceded by anything else:
:%s/pattern\(.*pattern\)\@!/replacement/
The part inside the parentheses is zero-width and not included in the match so is not replaced by the substitution.
:h \@!
for more information or :h pattern-multi-items
for the whole section containing other lookaround variations.