Regex Session 07: vim Regex
vim has its own regex flavor with unique quirks. Master vim regex and you can transform any file without leaving your editor.
vim Regex Modes
vim has four "magic" modes that change regex behavior:
| Mode | Prefix | Behavior |
|---|---|---|
magic (default) |
(none) |
Some chars need escaping: |
very magic |
|
ERE-like: |
nomagic |
|
Only |
very nomagic |
|
Nothing is special (literal matching) |
Recommendation: Use \v (very magic) for consistency with grep -E.
Search Basics
| Command | Purpose |
|---|---|
|
Search forward |
|
Search backward |
|
Next match |
|
Previous match |
|
Search for word under cursor |
|
Search backward for word under cursor |
Lesson 1: Very Magic Mode
Use \v at the start of pattern for cleaner syntax.
" Without \v (magic mode) - need to escape
/\(foo\|bar\)\+
" With \v (very magic) - cleaner
/\v(foo|bar)+
Practical Searches
" Find IP addresses
/\v\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}
" Find MAC addresses
/\v([A-Fa-f0-9]{2}:){5}[A-Fa-f0-9]{2}
" Find email addresses
/\v[A-Za-z0-9._%+-]+\@[A-Za-z0-9.-]+\.[A-Za-z]{2,}
" Find function definitions (Python)
/\vdef \w+\(
" Find variable assignments
/\v^\s*[a-z_]\w*\s*\=
Lesson 2: Substitution
Syntax: :[range]s/pattern/replacement/flags
Basic Substitutions
" Replace first occurrence on current line
:s/old/new/
" Replace all on current line
:s/old/new/g
" Replace all in file
:%s/old/new/g
" Replace with confirmation
:%s/old/new/gc
" Case-insensitive
:%s/old/new/gi
Range Specifiers
" Current line
:s/old/new/g
" Lines 5-10
:5,10s/old/new/g
" From current to end
:.,$s/old/new/g
" Entire file
:%s/old/new/g
" Lines matching pattern
:g/pattern/s/old/new/g
" Visual selection
:'<,'>s/old/new/g
Lesson 3: Capture Groups
vim uses \( and \) for capturing (or just () with \v).
Reference with \1, \2, etc.
" Swap first two words
:%s/\v(\w+)\s+(\w+)/\2 \1/
" Reformat date: 2026-03-15 → 03/15/2026
:%s/\v(\d{4})-(\d{2})-(\d{2})/\2\/\3\/\1/g
" Add quotes around values
:%s/\v(\w+)\=(\S+)/\1="\2"/g
" Duplicate line content: foo → foo foo
:%s/\v^(.+)$/\1 \1/
Lesson 4: Special Replacement Tokens
| Token | Meaning |
|---|---|
|
Entire match |
|
Capture group 1-9 |
|
Uppercase next character |
|
Uppercase until |
|
Lowercase next character |
|
Lowercase until |
|
End case conversion |
" Uppercase the match
:%s/\verror/\U&\E/g
" Result: ERROR
" Capitalize first letter of words
:%s/\v<(\w)(\w+)/\u\1\L\2/g
" UPPERCASE entire line
:%s/.*/\U&/
" lowercase entire match
:%s/ERROR/\L&/g
Lesson 5: The Global Command
Syntax: :g/pattern/command
Execute command on all lines matching pattern.
" Delete all comment lines
:g/^#/d
" Delete all blank lines
:g/^$/d
" Copy matching lines to end
:g/ERROR/t$
" Move matching lines to line 1
:g/TODO/m0
" Substitute only on matching lines
:g/DEBUG/s/old/new/g
" Execute normal mode commands
:g/pattern/normal dd
Inverse Global (:v)
" Delete lines NOT matching pattern
:v/ERROR\|WARN/d
" Keep only lines with IP addresses
:v/\v\d{1,3}\.\d{1,3}/d
Lesson 6: Lookaround in vim
vim supports lookahead/lookbehind with different syntax:
| vim Syntax | PCRE Equivalent |
|---|---|
|
|
|
End match here |
|
Lookahead |
|
Negative lookahead |
|
Lookbehind |
|
Negative lookbehind |
" Match only the number after 'port='
/port=\zs\d\+
" Matches: 8080 (not 'port=8080')
" Match word before colon
/\w\+\ze:
" Matches: 'key' in 'key: value'
" Match foo only if followed by bar
/foo\(bar\)\@=
" Matches: 'foo' in 'foobar', not 'foobaz'
Practical Workflows
Refactoring Variable Names
" Rename variable in entire file
:%s/\voldVar\b/newVar/g
" Rename only in function (with visual selection)
" 1. Select function with va{
" 2. Run substitution
:'<,'>s/\voldVar\b/newVar/g
Log Cleaning
" Remove timestamps
:%s/\v^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\s*//
" Extract only ERROR lines
:v/ERROR/d
" Anonymize IPs
:%s/\v\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/X.X.X.X/g
Code Formatting
" Add trailing comma to array elements
:%s/\v^(\s+\S.*)$/\1,/
" Convert snake_case to camelCase
:%s/\v_(\w)/\u\1/g
" Add semicolons to line ends (if missing)
:%s/\v([^;{])\s*$/\1;/
Config Modifications
" Comment out a section
:g/^\[database\]/.,/^\[/s/^/# /
" Uncomment lines
:%s/^# //
" Change config values
:%s/\vdebug\s*\=\s*\w+/debug = true/
Quick Reference Card
" SEARCH
/\vpattern " Very magic search
/pattern\c " Case insensitive
/pattern\C " Case sensitive
" SUBSTITUTE
:%s/old/new/g " All occurrences, all lines
:%s/old/new/gc " With confirmation
:5,10s/old/new/g " Lines 5-10
" CAPTURE GROUPS (very magic)
/\v(\w+) " Capture word
:%s/\v(\w+)/[\1]/g " Wrap in brackets
" CASE CONVERSION
\U \L \u \l \E " Upper/lower case
" GLOBAL COMMAND
:g/pattern/d " Delete matching lines
:v/pattern/d " Delete NON-matching lines
:g/TODO/t$ " Copy TODO lines to end
" LOOKAROUND
\zs " Start match here
\ze " End match here
Exercises to Complete
-
[ ] Search for all function definitions
-
[ ] Replace all IPs with "[REDACTED]"
-
[ ] Swap key=value to value:key format
-
[ ] Delete all blank lines and comments
-
[ ] Convert ALL_CAPS to Title_Case
Self-Check
Solutions
" 1. Function definitions
/\vdef \w+\(
" 2. Redact IPs
:%s/\v\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/[REDACTED]/g
" 3. Swap key=value
:%s/\v(\w+)\=(\w+)/\2:\1/g
" 4. Delete blanks and comments
:g/^$/d
:g/^#/d
" Or combined: :g/\v^(#|$)/d
" 5. ALL_CAPS to Title_Case
:%s/\v([A-Z])([A-Z]+)/\1\L\2/g
Next Session
Session 08: Python re Module - Regex in scripts and automation.