Vim multiline regex gives overlapping matches?

Up vote 1 down vote favorite share g+ share fb share tw.

I was surprised when I noticed that my greedy multiline regex was giving overlapping matches in Vim. The regex is designed to match an entire block of text, or consecutive non-blank lines. The regex apparently matched everything I expected it to (highlight looked correct), but when using n to skip to the next match instead of skipping to the next block, it went to the next line in the current block.

Here is the regex I was using (equivalent to (.+\n){1,} for most regex engines): \(.\+\n\)\{1,} This should match at least one non-empty line, and as many consecutive non-empty lines as possible, here is an example text file: block 1 some stuff more stuff block 2 foo bar baz qux After applying this regex (/\(.\+\n\)\{1,}+Enter) the two blocks are highlighted correctly, but I expect there to be only two matches of the regex, one for each block. However when I press n to advance to the next regex match it appears that each non-empty line matches the regex, so my cursor would start on the first line, n would take it to the second line, then third, then to the start of block 2 etc. How can I change my regex so that I see the expected behavior of each block being a single match so that n advances to the next block, instead of the next line? I am also interested in knowing if this behavior is in the documentation somewhere, or if there is an option to change this behavior.

Note that when using the same regex in a search/replace the behavior is what I expect (replacement would only be applied twice, once for each block). Regex vim vi link|improve this question asked 1 hour agoF. J19.7k11335 100% accept rate.

The following regex seems to work: \(\%^\|^\n. \@=\)\zs\(.\+\n\)* Explanation: \( # start of group \%^ # beginning of file \| # OR ^\n. \@= # a blank line followed by a non-blank line \) # end of group \zs # start matching here \(.\+\n\)* # any number non-blank lines Looking forward to seeing if anyone can come up with a shorter solution, or provide some explanation as to why Vim behaves this way in the first place!

Since your match says "match one or more non-empty lines" it can certainly match multiple times within the same paragraph. To fix this, you can specify that the cursor should be placed at the end of the match - the means the next match will start from the end of the paragraph. You can do this with the \zs zero-width character, available in vim: \zs Matches at any position, and sets the start of the match there: The next char is the first char of the whole match.

|/zero-width| So your match will become: \(.\+\n\)\{1,}\zs.

This allows me to jump to the end of each block which is nice for how simple the regex is, but I would like to have the entire block contained in the match if possible. – F. J 49 mins ago The block would be contained in the match, just the cursor will be positioned at the end of it.

Or do you mean something else? – zigdon 41 mins ago What I mean by "contained in the match" is that if you were to use the same regex in a search/replace, everything contained in the match would be replaced. Another equivalent meaning would be "the text that is highlighted".

– F. J 36 mins ago.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions