2

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

/\v<(\w+)\_s+\1>

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+).

8

\< 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:

berry
cherry
ferry

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:

xxx
cherry
xxx

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:

bxxx
cherry
fxxx

\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, privacy policy and cookie policy

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