2

If I want to find occurrences of the word 'arc', I can type / arc , with spaces around the three letters, to find basic occurrences of the word (ignoring punctuation). But suppose I want to find where two words are close together, say, within ten words? Here's an example:

Now is the time for all good men to come to the aid of their country.

In this test, I want to find all occurrences where the word 'aid' is within ten words of the word 'country'. How can I do that in Vim?

  • 1
    Also, instead of spaces you can use word boundaries: /\<arc\> – D. Ben Knoble Jul 26 '20 at 13:27
4

To find aid separated from country by at most 3 words, choose one:

  • /aid\(\W\+\w\+\)\{,3}\W\+country
    
  • /\vaid(\W+\w+){,3}\W+country
    

If words may be separated only by single space characters, it can be further simplified to

  • /\vaid( \w+){,3} country
    

Try it on this minimal, reproducible example:

Now is to the aid of their country.
Now aid of come their the country.

Only the first line should have a match, as it contains 2 words between aid and country, while the second line contains 4 words between aid and country.


The regex elements explained:

  • (\W+\w+) = a capture group, capturing \W+\w+.
    • \W+\w+ = 1 or more non-word characters followed by 1 or more word characters.
  • {,3} = The maximum number of occurrences of the capture group.

The very magic mode is enabled with a leading \v, so as to get rid of so much escaping in the non-magic counterpart.

  • BTW, why \W (non-word) instead of \s (whitespace). With the former, a distance of three, and target words "SS" and "EE" you'd get three matches in SS The quick brown EE fox jumped SS over twenty-two EE dogs at SS 3:12:20 EE last Thursday.. That looks like three, two and one word between SS/EE respectively. If you wanted the number and time to count as single words you'd want to replace \W with \s and \w with \S. Then this would have three matches: SS The quick brown EE fox jumped SS over twenty-two dogs EE at SS 3:12:20 last Thursday EE. – B Layer Sep 27 '20 at 14:51
  • @BLayer Indeed, that is relevant. The definition of word in the "regex world" is [A-Za-z0-9_], but linguistically twenty-two may be counted as a single word. I went for the first definition. – Quasímodo Sep 27 '20 at 20:06
  • There is no standard definition of "word" in regex land. And twenty-two is one word. The hyphen makes it so. Anyways, my goal was just to raise the issue for others to be aware of it rather than change anyone's mind. – B Layer Sep 27 '20 at 20:38
  • @BLayer In the "POSIX standard" sense, there is not, but it is the most common. I'm sure your goal is just to point out something relevant (it is!), but I cannot lose the chance to exchange ideas with the community :) – Quasímodo Sep 28 '20 at 16:48

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.