Search, Replace & Regular Expressions
If there's one chapter in this book that will save you hours of manual editing, it's this one. The ability to search for patterns and transform text across an entire file — or even across multiple files — is what turns Vim from a text editor into a text processing engine.
This chapter brings together three tightly connected topics: searching, regular expressions, and substitution. We cover them in one place because in practice you'll use them together. You'll search for a pattern, refine it until it matches exactly what you want, and then use it in a substitution to transform your text.
What you'll learn in this chapter:
Write Vim regular expressions using both default and very magic (
\v) syntaxSearch forward and backward, and configure search settings like incremental and smart-case matching
Perform substitutions with flags, expression registers, and custom delimiters
Search and replace across multiple files using
:vimgrepand the quickfix listApply practical regex patterns for tasks like reformatting dates, capitalizing text, and cleaning whitespace
Regular Expressions in Vim
Before diving into search and replace, let's establish a foundation with Vim's regex syntax. If you've used regular expressions in other languages, you'll feel mostly at home — but Vim has some quirks you should know about. The biggest difference is that many special characters require a backslash by default (unlike Perl/Python), which is why the \v (very magic) mode exists. Regex patterns pair especially well with text objects (see Text Objects) for selecting and operating on structured text.
Here's a reference of the most commonly used patterns:
^
Start of a line
$
End of a line
.
Any single character
\s
Whitespace
\S
Non-whitespace
\d
Digit (same as [0-9])
\w
Word character
\W
Non-word character
[a-z]
Lowercase letter
\w\+
One or more word characters
\v
Very magic mode (avoid many backslashes)
\zs
Start of match (everything before is context)
\ze
End of match (everything after is context)
\n
Newline in search pattern
\r
Newline in replacement
".\{-}"
Non-greedy match between quotes
\@!
Negative lookahead
Very Magic Mode \v
\vBy default, Vim requires many backslashes in regex. The \v (very magic) flag makes most special characters work without escaping:
Tip: Start your search patterns with
\vto write cleaner regex.
Basic Search
/pattern
Search forward
?pattern
Search backward
n
Next match
N
Previous match
*
Search word under cursor (forward)
#
Search word under cursor (backward)
Search Settings
Neovim: These are mostly default in Neovim. You can clear highlights with
:nohlsearchor map it to a key.
Interactive Search Navigation
While typing a search pattern in the command line, you can use:
Ctrl+g
Jump to the next match while still typing
Ctrl+t
Jump to the previous match while still typing
This lets you preview and cycle through matches before pressing Enter to confirm.
Searching with Hexadecimal Notation
Search for non-breaking spaces or other special characters using hex:
Use ga to show the hex value of the character under the cursor.
Substitution Basics
The general form is:

Common Flags
g
Replace all occurrences on each line (not just the first)
c
Ask for confirmation before each replacement
i
Case-insensitive for this substitution
I
Case-sensitive for this substitution
e
Don't show error if pattern not found
n
Count matches without replacing
Changing the Delimiter
You don't have to use /. Any character works:
Reusing the Last Search
Substitution Tricks
Using the Expression Register in Substitutions
The \= in the replacement part lets you evaluate Vimscript:
Using the Ampersand &
&The & in the replacement represents the entire match:
Conditional Replacement
Use a ternary operator in the expression:

Converting Date Formats
Toggling Words with Regex
Exchange the last two words on each line:
Tip: The advantage of using regex groups
()is that you can refer to them with\1,\2, etc.
Multiline Search
To search across multiple lines, use \_ prefix:
Pattern Not Followed By Another Pattern
Use \@! for negative lookahead:
Searching Across Files
vimgrep
Quickfix Navigation
After vimgrep, results appear in the quickfix list:
:copen
Open quickfix window
:ccl or :cclose
Close quickfix window
:cn
Jump to next entry
:cp
Jump to previous entry
:cdo {cmd}
Execute command on each quickfix entry

Neovim: Telescope with
live_grepand trouble.nvim provide a much better experience for searching across files.
Regex Analysis: The DelBlank Function
The DelBlankLines function (see Chapter 5) uses three substitution commands. Here's a breakdown of each regex:
First: :%s/\s\+$//e — Remove trailing whitespace
\s
Space or tab
\+
One or more
$
At end of line
Second: :%s/^\n\{2,}/\r/ge — Squeeze consecutive blank lines into one
^
Start of line
\n
Line break
\{2,}
Two or more times
\r
Replace with single newline
Third: :%s/\v($\n\s*)+%$//e — Remove trailing blank lines at end of file
\v
Very magic mode
($\n\s*)
End of line + newline + optional spaces (one group)
+
One or more of this group
%$
End of file
Note: All three use the
eflag to suppress "pattern not found" errors.
Practical Examples
Capitalize First Letter of Each Word in a Selection
The %V restricts the substitution to the visual selection.
Capitalize First Word After Punctuation
[.?!]
Period, question mark, or exclamation point
\_s*
Any whitespace including newlines
\zs
Start match here
\<\w\+\>
A whole word
\U&
Uppercase the match
Note: Notice the delimiter is
;to avoid conflicts with/in the pattern.
Remove Trailing Whitespace
Delete Blank Lines
Add a Blank Line After Each Non-Empty Line
Use Current Word in Commands
Press Ctrl+rCtrl+w in command mode to insert the word under the cursor:
Tip: The search and substitution patterns covered in this chapter become even more powerful when combined with the
:globalcommand (see The Global Command), which lets you apply commands selectively to lines matching a pattern.
Summary
Vim's search, substitution, and regex capabilities transform it from a text editor into a text processing engine. By combining forward and backward search, very magic regex syntax, and the flexible substitution command with its flags and expression register, you can perform text transformations that would otherwise require external scripts. Searching across files with :vimgrep and applying changes via the quickfix list extend these capabilities to entire projects.
Key takeaways:
Use
\v(very magic) mode to write cleaner regular expressions that avoid excessive backslash escaping.The substitution command supports powerful features like the expression register (
\=), the ampersand (&) for the full match, and custom delimiters.Combine
:vimgrepwith:cdoto search and replace across multiple files in a single workflow.The
\zsand\zeatoms let you define match boundaries within a larger pattern, giving you surgical precision.
Exercises
Search with very magic mode — Open any file and search for all words that start with a capital letter followed by at least two lowercase letters. Use
\vmode to keep the pattern clean.Substitute with confirmation — Replace all occurrences of
foowithbarin the current file, but confirm each replacement before it happens. Skip any occurrences you want to keep.Swap two words using capture groups — Given a line like
first_name last_name, write a substitution that swaps the two words so it becomeslast_name first_name. Use very magic mode.Use the expression register in substitution — Given a file with lines like
Price: 100,Price: 250, write a substitution that doubles every price number.Search and replace across files — Use
:vimgrepto find all occurrences ofold_functionin every.pyfile in the current directory tree. Then replace them all withnew_functionusing:cdo.
Last updated
Was this helpful?