How to Use Regex Find and Replace in VS Code (2026)
A practical guide to regex find and replace in VS Code: capture groups, $1 substitution, case modifiers, and the side-by-side diff preview.
How to Use Regex Find and Replace in VS Code
Regex find and replace in VS Code turns a tedious manual edit into a single, reviewable operation. The problem is that most developers stop at literal search and never touch the .* button — so they hand-edit 200 call sites that one capture group could have rewritten. This guide covers the regex toggle, capture-group substitution with $1, the case modifiers unique to VS Code, and the side-by-side diff preview that lets you verify every change before committing it.
TL;DR
- Enable regex with the
.*icon in Find (Ctrl+F) or Search (Ctrl+Shift+F), or press Alt+R. - Reference capture groups in the replace box with
$1,$2;$0or$&is the whole match. - Case modifiers
\u \l \U \Ltransform captured text — a VS Code extra, not JS regex. - Project-wide replace shows a live diff you can apply per change, per file, or all at once.
- VS Code uses JavaScript's RegExp engine, so PCRE-only syntax fails silently.
How to do regex find and replace in VS Code
The feature lives in two places: the in-file Find widget and the project-wide Search view. They share the same regex engine but suit different jobs.
Enable regex in the Find widget
Press Ctrl+F (Cmd+F on macOS) to open Find inside the current file, then expand it into replace mode with the chevron on the left or Ctrl+H. On the right of the search box sit three toggles — Match Case, Match Whole Word, and Regular Expression — plus a Preserve Case toggle on the replace row. Click the .* icon (or press Alt+R) to switch on regex; it highlights when active. The official VS Code basic editing docs list these same four options, so you are not relying on an extension for any of it.
Once regex is on, VS Code searches as you type and highlights matches in the editor, the overview ruler, and the minimap. That live highlight is your first correctness check: if the wrong things light up, fix the pattern before you touch replace.
Scope a replace with Find in Selection
For a risky pattern, select the block you want to touch first, then click Find in Selection (Alt+L) in the Find widget. Now the replace only fires inside that selection, which is the safest way to try a substitution on one function before letting it loose on the file. You can make this the default with the editor.find.autoFindInSelection setting.
Go project-wide with the Search view
Press Ctrl+Shift+F (Cmd+Shift+F) to open the Search view, expand the replace field, and toggle the same .* icon. This runs across every file in the workspace, honoring your .gitignore and search.exclude rules. Use the files to include and files to exclude boxes to fence the operation to, say, src/**/*.ts before a large rename.
How to reference capture groups in the replace field
Capture groups are what separate find-and-replace from a glorified typo fixer. Anything you wrap in parentheses is captured and can be re-inserted, reordered, or reshaped in the output.
Using $1, $2, and $0
A capture group is referenced in the replace box by $n, where n is the position of the group. $0 (equivalently $&) is the entire match, $1 is the first parenthesized group, $2 the second, and so on — the same $-substitution convention JavaScript uses in String.prototype.replace. Say you have a file full of imports written with double quotes and you want single quotes only on relative paths:
Find: import (.+) from "(\./.+)"
Replace: import $1 from '$2'
$1 keeps the imported bindings untouched; $2 re-inserts the path, now wrapped in single quotes. Nothing else in the line is at risk because you only rewrote what you explicitly captured.
Reordering and named groups
Because $n can appear in any order, swapping two fields is trivial. To flip first,last CSV columns into last,first:
Find: ^(\w+),(\w+)$
Replace: $2,$1
VS Code also honors named groups in the pattern — (?<year>\d{4}) — though in the replace box you still reference them positionally as $1. If you want a refresher on the capture-group syntax itself, MDN's guide to groups and backreferences is the primary reference, and you can prototype the pattern in iKit's Regex Tester before pasting it into the editor.
Escaping a literal dollar sign
Since $ is the substitution character, a literal $ in your output needs to be written $$. Replacing a price placeholder with $$$1 emits $ followed by whatever group 1 captured.
How to change case during find and replace in VS Code
This is the trick most people miss, and it is genuinely VS Code specific — you will not find it in a standard regex reference because it is a replacement feature layered on top.
The \u \l \U \L modifiers
VS Code can transform the case of a captured group inside the replace string. Per the VS Code docs, \u and \l upper/lowercase a single character, while \U and \L upper/lowercase the rest of the group. So to title-case a lowercase word:
Find: \b([a-z])(\w*)
Replace: \u$1$2
To scream a constant name in uppercase, capture it and prefix \U:
Find: const (\w+) =
Replace: const \U$1 =
Stacking modifiers
The modifiers stack. \u\u\u$1 uppercases the first three characters of the group; \l\U$1 lowercases the first character and uppercases the rest. That combination is exactly how you convert a PascalCase type into a cONSTANT-style token in one pass — niche, but when you need it, nothing else does it as cleanly. For bulk case conversion outside an editor context, iKit's Case Converter handles camelCase, snake_case, and kebab-case in the browser.
Here is how the modifiers behave on the input word banana:
| Replace pattern | Output |
|---|---|
$1 |
banana |
\u$1 |
Banana |
\U$1 |
BANANA |
\u\U$1 |
BANANA |
Note the empty case where a match has no group — always capture the text you intend to transform, because a bare \U with nothing after it does nothing.
Why won't my regex match in VS Code
When a pattern that worked in a tester fails in the editor, the cause is almost always the engine or the flags, not your regex logic.
JavaScript engine, not PCRE
VS Code searches with JavaScript's RegExp engine. That means PCRE-only constructs — recursion, atomic groups, possessive quantifiers, \K, inline (?i) flags — are unsupported and will simply fail to match rather than throw a clear error. If you copied a pattern from a PHP or Perl codebase, that mismatch is the usual culprit. We cover these dialect gaps in depth in the JavaScript vs PCRE vs Python regex post.
Implicit flags and multiline behavior
You do not type /g or /i in VS Code. Global is always on for replace-all. Case sensitivity is controlled by the Match Case toggle, not an i flag. And ^ / $ anchor to line boundaries because search runs in multiline mode, so ^import matches the start of every line, not just the file. Keep a short mental checklist:
.does not match newlines unless you write[\s\S]or[^].- Backreferences in the pattern use
\1; substitutions in the replace use$1. - A literal newline in the replace box is written
\n; press Ctrl+Enter to insert a real one while typing.
Preview before you commit
The single most important habit: in the Search view, typing into the replace box renders a diff of every pending change across all matched files. VS Code shows each hit struck through with its replacement beside it, and you can apply changes one at a time, one file at a time, or all at once. Treat that preview like a side-by-side review — scan it the way you would a git diff. If the preview surprises you, your pattern is wrong, and you just caught it for free. When you want a dedicated before/after comparison of two whole files rather than an inline preview, iKit's Diff Checker does it entirely in the browser.
References
- Basic editing in Visual Studio Code — official docs; source for the find/replace options, the
\u\U\l\Lcase modifiers, and$ncapture-group referencing. - MDN: String.prototype.replace() —
$n,$&, and$$substitution semantics that VS Code mirrors. - MDN: Groups and backreferences — capture-group and named-group syntax in JavaScript's RegExp engine.
Related on iKit
- Test any pattern before a bulk replace with the Regex Tester — prototype your VS Code pattern against sample text before you run it across a whole workspace.
- Capture groups, $1, $& and named references explained — the deep dive on the exact substitution syntax this article uses in the replace box.
- Why your regex fails across JavaScript, PCRE, and Python — the engine differences behind most "works elsewhere, not in VS Code" bugs.
- The 2026 regex cheatsheet of 25 everyday patterns — reference for the tokens you'll drop into VS Code's find box.
- Extract timestamps and IPs from logs with regex — a real capture-group workflow you can adapt to find-and-replace.
Related posts
How to Find a Single Typo in a 5,000-Line File (2026)
Find a single typo in a large file fast: use a word- and character-level diff to pinpoint the one changed character instead of scanning 5,000 lines.
Compare Two Markdown Drafts Without Word Track Changes (2026)
How to compare two Markdown drafts without Word's Track Changes: use a diff checker, git word-diff, or CriticMarkup to see every real edit in plain text.
How to Compare Two JSON Files Without False Diffs (2026)
Learn how to compare two JSON files without key-order and whitespace noise. Normalize first, sort keys with jq, and diff only the changes that matter.