Mastering Regular Expressions in Vim
Vim’s regex engine is powerful but requires understanding its syntax rules, which differ significantly from standard POSIX extended regex. Whether you’re doing basic substitutions or complex text transformations, knowing how Vim handles regex patterns will save you hours of frustration.
Vim Regex Basics
Vim supports multiple regex engines, controlled by the magic setting. By default, Vim uses magic mode, which interprets most characters literally except for special metacharacters. However, the syntax differs from what you might expect from grep or sed.
Key characters in Vim regex:
.— matches any single character*— matches zero or more of the preceding character\+— matches one or more (requires backslash escape in standard mode)\?— matches zero or one\{n,m}— matches between n and m occurrences^— start of line$— end of line\<and\>— word boundaries\(and\)— capture groups (requires backslash escape in standard mode)|— alternation (requires backslash escape:\|in standard mode)
Magic vs Nomagic
Vim has different regex modes that affect which characters require escaping:
:set magic (default) — most metacharacters work as expected, but parentheses and pipes need backslashes
:set nomagic — almost everything needs escaping, limiting usefulness
:set smartcase and :set ignorecase — control case sensitivity in patterns
To use extended regex syntax without backslashes, use \v at the start of your pattern (very magic mode):
:%s/\v(foo|bar)+/matched/g
Or use \V for very nomagic (literal matching):
:%s/\V.*literal.*/replacement/g
Practical Substitution Examples
Basic find and replace:
:%s/old/new/g
Replace with capture groups:
:%s/\(foo\)\(bar\)/\2\1/g
In very magic mode (cleaner syntax):
:%s/\v(foo)(bar)/\2\1/g
Case-insensitive replacement:
:%s/foo/bar/gi
Replace only in visual selection:
:'<,'>s/old/new/g
Replace on specific lines:
:10,20s/old/new/g
Conditional replacements with backreferences:
:%s/\v(\w+)@<!=\s*/-/g
This removes spaces before equals signs but only when not preceded by a word character.
Working with Character Classes
Character classes provide shortcuts for common patterns:
\d— digit (equivalent to[0-9])\D— non-digit\w— word character[a-zA-Z0-9_]\W— non-word character\s— whitespace\S— non-whitespace
Example: Remove trailing whitespace from all lines:
:%s/\s+$//g
Extract numbers from a line and keep only them:
:%s/\v[^0-9]+//g
Global Command Patterns
The :g command uses regex to execute commands on matching lines:
:g/^#/d
Delete all comment lines starting with #.
:g/\v^[[:space:]]*$/d
Delete all blank lines (including those with only whitespace).
:g/pattern/norm dd
Delete lines matching a pattern using normal mode commands.
Invert the match with :v:
:v/keep/d
Delete all lines that don’t contain “keep”.
Performance Considerations
Complex regex patterns can slow down Vim on large files. If substitution is sluggish:
- Use anchors (
^and$) to narrow the search scope - Prefer specific patterns over broad ones
- Use
:set nocursorlinetemporarily to improve performance - Consider processing files with external tools for intensive regex work
For massive file processing, sed or awk are often faster:
sed 's/old/new/g' file.txt > output.txt
Debugging Regex Patterns
Use :set showcmd to see what you’re typing. Test patterns incrementally:
- Start with
/patternto search and verify it matches correctly - Once confirmed, use
:%s/pattern/replacement/g
Vim’s built-in incremental search provides immediate visual feedback. Use <Ctrl-L> to add characters to the search one at a time.
Learning Resources
Vim’s built-in help is comprehensive:
:help pattern
:help regex
:help /magic
:help \v
Refer to these when experimenting with new patterns. The :helpgrep command searches across all help files:
:helpgrep word_boundary
Practice with real files in your own environment — regex intuition comes through repeated use, not memorization.
