Search code examples
vimsubstitution

Vim Multi-line search pattern


I have a substitute command that captures and displays submatch() values in the replacement string. But I have another line of information that I want to parse below this line. That line is always the first line after an empty line, though the number of lines TO that empty line varies. For example:

The first important line I want to capture is here
Stuff I don't want.
A few more lines of stuff I don't want...

Second line I want to capture.

This pattern repeats a hundred or so times in a document. I can substitute "The First Important Line" fine, but shouldn't that search pattern include a way to jump down to the first empty line and then pick up the next "Second line I want to capture." ?? I could then place the contents of that second line into submatch parenthesis and substitute them where needed (right?).

If so, I cannot discover the way to extend the first search pattern to capture the "Second line" Suggestions or correcting my approach would be greatly appreciated.


Solution

  • Someone has already dealt with a similar problem. Below I provide their solution and the detailed description.

    /^\nF\d\_.\{-}\_^\n\zs.*/+

    It means "Find a block of lines that start with F and a digit, then scan forward to the next blank line and select the line after that."

    Part of regex Meaning
    ^\n Matches the start of a line, followed by a newline - i.e a blank line
    F\d The next line starts with an F followed by a digit
    \_.\{-} \_. is like ., but also matches newline. \{-} matches the minimum number of the preceeding \_.. (If I were to use * instead of \{-}, it would match to near the end-of file.)
    \_^\n Matches a blank line. \_^ is like ^, but ^ only works at the start of a regular expression.
    \zs When the match is finished, set the start of match to this point. I use this because I don't want the preceding text to be highlighted.
    .* Matches the whole line.

    The + after the regular expression tells Vim to put the cursor on the line after the selection.