7

I have such lines in my text.

text before pattern = garbage** text after pattern is pattern

If in VIM I do %s/pattern/saturn/ it replaces all occurrences of pattern. But I only want to replace those occurrences that come after =. It should ignore everything in the line that occurs before =. How to do that?

0

2 Answers 2

4

Assuming you have only one occurrence of pattern before =, you can do this in two steps:

:%s/pattern/saturn/g
:%s/saturn\(.\{-}=\)/pattern\1/

The \{-} instructs . to match lazily (aka non-greedily).

Explanation

This first step replaces all the occurrences of pattern by saturn the next step then looks for the word saturn before = and replaces it with pattern.

Caution

This assumes a single occurrence of = on each line.

A better way (only assumes a single = per line)

You can do it with a recursive macro:

qaqqa:%s/\(=.\{-}\)pattern/\1saturn/@aq@a

This substitutes a single occurrence of pattern after = with saturn. When stored as a macro and called recursively it will keep working on the file until there's nothing left to substitute. It's hackish but it works.

See also

8
  • Will this replace all occurrences of pattern after =? How? I don't know how many there will be beforehand.
    – user13107
    Sep 19, 2013 at 18:31
  • @user13107 My original answer replaced only a single instance of pattern after =. Please see the updated answer.
    – Joseph R.
    Sep 19, 2013 at 18:41
  • Thanks mate, that was clever, unfortunately there are an unknown number of them before = :( argh
    – user13107
    Sep 19, 2013 at 18:47
  • @user13107 I have a hack to work around this. Will post when I have time.
    – Joseph R.
    Sep 19, 2013 at 19:12
  • this also assumes that the string saturn isn't in the text. probably true, but i'd be inclined to use something a lot more obscure/unique as the temporary substitute string - myhamsterlivesonsaturn, perhaps :)
    – cas
    Sep 20, 2013 at 3:24
3

You can use the special atom \@<= to assert a match before (=.* to make it anywhere before in that line):

:%s/\(=.*\)\@<=pattern/saturn/g
3
  • could you explain how this works?
    – user13107
    Sep 21, 2013 at 10:47
  • 1
    Read :help /\@<= (I can't explain it better), but don't feel bad when you don't get it first. It's called positive lookbehind, and is quite advanced. Sep 21, 2013 at 15:09
  • +1 Really elegant. The interesting thing is, variable width lookbehind isn't supported in Perl! I never thought the Perl regex engine would ever be lacking something other engines have.
    – Joseph R.
    Sep 21, 2013 at 20:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .