15

Many Unix tools' regular expression syntaxes are often the POSIX-codified Basic and Extended Regular Expressions (BRE and ERE, respectively), and, in some modern implementations, Perl-style (PCRE being an implementation of this).

Is there a one-to-one correspondence between Vim's levels of magic and such externally defined, but well-known, classes? It looks like \m is BRE and \v is ERE, except POSIX doesn't include lookarounds.

If such a correspondence exists, is it defined somewhere? pattern.txt has only one mention of POSIX.

Or do we have to stick with "magic" to describe Vim regular expressions?

  • 3
    Pretty sure \v includes <> word boundaries, which AFAIK is unique to Vim. So no, just describe them as "Vim regex." (Not posting as an answer because I'm not positive) – Doorknob Feb 27 '15 at 16:50
  • @Doorknob, I think you might find find this discussion of answers-as-comments interesting. Since your comment has three upvotes and no comments responding to tell you it's incorrect, it's probably correct (I'm not sure), but suggested edits et. al. are impossible to improve its accuracy. As a posted answer, it could be edited for improved accuracy, upvoted, downvoted, responded to, etc. – Wildcard Apr 4 '16 at 20:23
21

In summary, no. Vim's regex is a unique flavour, and there are no options to make it behave more like another flavour.

I think this is a good thing.

Magic

The 'magic' option doesn't change the flavour of regex that Vim uses. It simply inverts the behaviour of many \-escaped atoms.

For example, by default, + is a literal + character, where \+ means "one or more of the preceding atom". In contrast, * means "zero or more of the preceding atom", while \* is a literal *. Many people find this quite confusing. Using \v in your pattern makes it a bit more consistent. :help 'magic' gives a good summary:

after:    \v       \m       \M       \V         matches ~
                'magic' 'nomagic'
          $        $        $        \$         matches end-of-line
          .        .        \.       \.         matches any character
          *        *        \*       \*         any number of the previous atom
          ()       \(\)     \(\)     \(\)       grouping into an atom
          |        \|       \|       \|         separating alternatives
          \a       \a       \a       \a         alphabetic character
          \\       \\       \\       \\         literal backslash
          \.       \.       .        .          literal dot
          \{       {        {        {          literal '{'
          a        a        a        a          literal 'a'

Personally, I think the default behaviour is nice for code files, where it's not uncommon to search for things like foo(, using the literal (.

Vim's own regex flavour

I've witnessed many people wishing Vim supported PCRE. Personally, I wish other tools supported Vim's flavour of regex. It has some capabilities that are either impossible or too cumbersome to achieve in PCRE.

Impossible in PCRE

Lookaround is a common feature where you can assert that a pattern either does or does not match before or after the pattern you're trying to match. For example, the PCRE pattern q(?!u) (or Vim regex pattern qu\@!) matches a q that's not followed by a u. (This is more correct than q[^u], which requires that there is some character after the q.)

Variable-length negative lookbehind

PCRE, and many other flavours, have a restriction that a negative lookbehind pattern must be of a fixed length. That means that a pattern like (?<![a-z]{3})foo, meaning "the string foo not preceded by exactly 3 lowercase letters") is fine, but (?<![a-z]+)foo (meaning "the string foo not preceded by any number of lowercase letters") is not.

This restriction doesn't exist in Vim. In Vim, a pattern like \([a-z]\+\)\@<!foo, while maybe a bit ugly to look at, is perfectly valid.

Easier in Vim regex

Some things are a lot nicer in Vim's flavour of regex.

Start and end of match anchors

The most notable, in my opinion, are the \zs and \ze anchors. These allow you to specify the start and end of the match. For example, foo(\zs.*\ze) matches only what's between the ( and ) in a function call like foo(...). This can be done in PCRE, but it requires the use of lookaround, which is slightly tedious: (?<=foo\().*(?=\))

Prefix matching

Another cool thing that Vim can do is match any prefix (including the empty prefix) of a particular sequence of characters. For example, to match on f, fo, foo, or food, the pattern f\%[ood] can be used. In PCRE, such a pattern would look like f(o(od?)?)?. (Imagine that for a longer string!)

Matching cursor, line, and column positions

Vim's regex has some anchors for matching positions in the buffer.


I think it's worth-while to embrace Vim's flavour of regex. It's well-suited for use in a text editor used primarily for programming, and it's quite powerful.

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.