Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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?

share|improve this question

2 Answers 2

up vote 2 down vote accepted

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

:%s/\(=.*\)\@<=pattern/saturn/g
share|improve this answer
    
could you explain how this works? –  user13107 Sep 21 '13 at 10:47
    
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. –  Ingo Karkat Sep 21 '13 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 '13 at 20:10

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

share|improve this answer
    
Will this replace all occurrences of pattern after =? How? I don't know how many there will be beforehand. –  user13107 Sep 19 '13 at 18:31
    
@user13107 My original answer replaced only a single instance of pattern after =. Please see the updated answer. –  Joseph R. Sep 19 '13 at 18:41
    
Thanks mate, that was clever, unfortunately there are an unknown number of them before = :( argh –  user13107 Sep 19 '13 at 18:47
    
@user13107 I have a hack to work around this. Will post when I have time. –  Joseph R. Sep 19 '13 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 '13 at 3:24

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.