# Vim Search and Replace With Special Characters - Escape Sequences Guide

You need to replace all occurrences of C:\Users\Documents with /home/user/docs in a configuration file. You type :%s/C:\Users\Documents/\/home\/user\/docs/g and Vim responds with Pattern not found or makes a mess of your file. Special characters in search patterns are a common stumbling block because Vim's search uses regex syntax where characters like `, /, and .` have special meanings.

Understanding Vim's Search Syntax

Vim has two regex modes: "magic" and "very magic". By default, you're in magic mode where some characters need escaping and others don't:

  • - Always needs escaping as \`
  • / - Needs escaping as \/ when used as the delimiter
  • . - Matches any character (escape as \. for literal dot)
  • * - Matches zero or more (escape as * for literal asterisk)
  • [] - Character class (escape as [ and ] for literal brackets)
  • ^ - Start of line (escape as \^ for literal caret)
  • $ - End of line (escape as \$ for literal dollar)

Changing the Search Delimiter

The most common issue is that your search or replacement contains /. Instead of escaping every /, use a different delimiter:

vim
:%s#C:\Users\Documents#/home/user/docs#g
:%s|http://example.com|https://example.org|g
:%s@/old/path/@/new/path/@g

Any non-alphanumeric character works as a delimiter. The #, |, and @ are popular choices because they rarely appear in text.

Escaping Backslashes

Backslashes are tricky because they're both the escape character and often part of the content you're searching for. For a literal backslash, use \:

vim
:%s/\\n/\n/g

This replaces the literal text \n with an actual newline character.

For Windows paths, escape each backslash:

vim
:%s/C:\\Users\\Documents/\/home\/user\/docs/g

Or use a different delimiter to avoid confusion:

vim
:%s#C:\\Users\\Documents#/home/user/docs#g

Special Characters in Replacement Strings

The replacement side of :s has its own special characters:

  • \0 or & - The entire matched text
  • \1, \2, etc. - Captured groups
  • \n - Newline character
  • \t - Tab character
  • \ - Literal backslash
  • \r - Carriage return

To use these literally, escape them:

vim
:%s/foo/\&bar/g    " Replaces "foo" with "&bar"
:%s/foo/\\t/g      " Replaces "foo" with "\t"

Very Magic Mode for Less Escaping

Use \v at the start of your pattern to make all alphanumeric characters literal and all other characters special:

vim
:%s/\vC:\\Users\\Documents/\/home\/user\/docs/g

This doesn't help with backslashes, but it helps with other special characters.

For the replacement side, use \= to evaluate an expression:

vim
:%s/\d\+/\=submatch(0) * 2/g

This doubles every number in the file. submatch(0) is the entire match.

Newlines and Multi-line Patterns

Vim handles newlines differently in search versus replacement:

In the Search Pattern

  • \n matches a newline character
  • \r matches a carriage return
  • \_s matches any whitespace including newlines
  • \_. matches any character including newlines

Replace text across multiple lines:

vim
:%s/Line one\nLine two/Replaced text/g

In the Replacement String

  • \r inserts a newline (not \n!)
  • \n inserts a null character

This is counterintuitive but important:

vim
:%s/, /,\r/g    " Replaces ", " with ", " followed by newline

Character Classes and Special Escapes

Vim provides convenient character classes:

vim
\d    " Digit [0-9]
\D    " Non-digit [^0-9]
\s    " Whitespace [ \t]
\S    " Non-whitespace
\w    " Word character [a-zA-Z0-9_]
\W    " Non-word character
\l    " Lowercase letter [a-z]
\u    " Uppercase letter [A-Z]
\x    " Hex digit [0-9a-fA-F]

For Unicode categories:

vim
\p{Ll}    " Lowercase letter (Unicode)
\p{Lu}    " Uppercase letter (Unicode)
\p{N}     " Any number

Practical Examples

Replace Tabs with Spaces

vim
:%s/\t/    /g    " Replace each tab with 4 spaces

Fix Windows Line Endings

vim
:%s/\r$//g    " Remove carriage returns at end of lines
:set ff=unix   " Set file format to Unix

Or simply:

vim
:set ff=unix
:w

Escape HTML Entities

vim
:%s/&/\&/g
:%s/</\&lt;/g
:%s/>/\&gt;/g

Replace with Incrementing Numbers

vim
:let i=0
:%s/item \d\+/\='item ' . (i += 1)/g

This replaces "item 123", "item 456", etc. with "item 1", "item 2", etc.

Swap Words Using Groups

vim
:%s/\(\w\+\) \(\w\+\)/\2 \1/g

This turns "first last" into "last first".

Using very magic mode for cleaner syntax:

vim
:%s/\v(\w+) (\w+)/\2 \1/g

Match at Start or End of Line

vim
:%s/^    /\t/g      " Replace 4 spaces at start of line with tab
:%s/\s\+$//g         " Remove trailing whitespace

Case-Insensitive Search

Add \c for case-insensitive or \C for case-sensitive:

vim
:%s/\cfoo/bar/g      " Replace foo, FOO, Foo, etc.
:%s/\CFoo/bar/g      " Replace only exact "Foo"

Or use flags:

vim
:%s/foo/bar/gi       " The 'i' flag makes it case-insensitive

Literal Search Without Regex

Use \V for very nomagic mode, where everything is literal except ``:

vim
:%s/\VC:\Users\Documents/\/home\/user\/docs/g

Only backslashes need escaping in this mode.

Confirmation Mode

For complex substitutions, use the c flag to confirm each replacement:

vim
:%s/old/new/gc

Vim will prompt at each match:

  • y - Yes, replace
  • n - No, skip
  • a - All remaining (no more prompts)
  • q - Quit
  • l - Replace this and last
  • ^E - Scroll down
  • ^Y - Scroll up

This is invaluable when your pattern might match unintended text.

Debugging Patterns

If your substitution isn't working, test the search pattern first:

vim
/your pattern

Use :match to highlight matches:

vim
:match Search /pattern/

Check what Vim sees with the search register:

vim
:echo @/

This shows the last search pattern, which is what :s uses by default if you don't specify a pattern.

Special characters in Vim's search and replace require careful attention, but once you understand the escaping rules and alternative delimiters, you can transform any text. Remember: change your delimiter if it appears in your text, escape backslashes twice, use \r for newlines in replacement strings, and leverage very magic mode to reduce escaping.