2

Given the following example:

aa
aa
bb
bb
cc
dd

I'm trying to replace two-line match (bb\nbb) with its first matching line (bb).

What works:

  • these two-lines can be matched by: /bb\_.\{-}bb (as per: Search across multiple lines),
  • I can replace two-line match with hardcoded one-line string: %s/bb\_.\{-}bb/foo/g.

What doesn't work:

  • I can't use first backreference (\1) instead of hardcoded string, so when using:

    %s/bb\ze\_.\{-}bb/\1/g
    

    as result of just adding \ze and \1 to the previous example, I expect that this two-line pattern would be replaced by its backreference value (so bb\nbb becomes bb), but instead it removes the 1st line and not touching the 2nd. (so bb\nbb becomes: \nbb).

Any idea why the following attempt doesn't work? I don't want to join and remove the second line, I'd like to understand what's the problem and what's the correct way of doing it.

4

I can't use first backreference (\1) instead of hardcoded string

Well, you haven't captured anything in the search so \1 has no value in the replacement.

You can use a matched text later in the pattern, as a back-reference, as well as in the replacement.

:%s/^\(.*\)\n\1/\1/

This allows you to find a line (\(.*\)) which has a duplicate line immediately following it (\n\1) and remove that duplicate by replacing the search with just the grouped match.

However, this can be simplified by simply starting the match after the initial line and removing all the matched content:

:%s/\(.*\)\zs\n\1//
  • Thanks, I thought using \zs/\ze is enough to catch the previous reference value, but it seems the brackets are mandatory. – kenorb Aug 12 '15 at 13:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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