In the Practical Vim book, there is an example of a regular expression that matches duplicate words:


While this works beautifully, I don't quite understand why it also matches the a a part in Once upon a a time.. I mean, shouldn't the < be same as \W\zs\w and > same as \w\ze\W? If yes, then already the beginning of the regex(/\v\W\zs\w(\w+)...) should require at least two consecutive word characters because of \w(\w+).

  • 2
    \< and \> do not use \zs and \ze! They are zero-width characters.
    – DJMcMayhem
    Aug 11, 2016 at 22:17

1 Answer 1


\< and \> are zero-width word boundaries. They allow you to match the beginning and end of words without moving the cursor that's currently evaluating the character.

The difference between \W and \< \> is that \W is simply [^0-9A-Za-z_] whereas \< \> are affected by 'iskeyword' which can be different depending on the filetype. In some files, hypenated-word is one word, while in others it's two words separated by a non-word character.

\zs and \ze are zero-width atoms that set the boundaries for capture group \0. They are useful for changing what is considered a match.

For instance, you have a list of words:


You want to replace erry in everything below, but not when h comes before it. A substitution like %s/[^h]erry/xxx/g would result in:


It didn't replace cherry, but it replaced the character that came before erry in the other words. This is because [^h] is still part of the match.

You can use \zs to set the beginning of the match for the substitution with %s/[^h]\zserry/xxx/g, which will give you:


\ze works the same way, but sets where the match ends.

\zs and \ze are particularly useful with the search() and matchstr() functions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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