TL;DR
- โข Regex find and replace lets you match patterns, not just exact strings
- โข Use capture groups
(\w+)and reference them with $1, $2 in replacement - โข The g flag replaces all matches, not just the first
- โข Multi-rule mode applies several replacements in sequence โ powerful for complex transforms
- โข Test your patterns before applying to production data
Table of Contents
- 1. What makes regex find and replace different from plain find and replace
- 2. The five regex concepts you actually need
- 3. Capture groups: the most powerful replacement feature
- 4. Real-world examples with full patterns
- 5. Multi-step replacement workflows
- 6. Regex find and replace in different tools
- 7. Common mistakes and how to avoid them
- 8. When NOT to use regex
- 9. FAQ
1. What Makes Regex Find and Replace Different
Plain find and replace looks for an exact string. If you search for "colour" and replace with "color", it works perfectly for that one word. But what if you want to find every date in the format DD/MM/YYYY and change it to YYYY-MM-DD? Or remove every HTML tag? Or rename every function that starts with <code>get_</code> to start with <code>fetch_</code>? You cannot describe those patterns as exact strings.
Regex (regular expression) find and replace lets you write a pattern instead of a fixed string. The pattern describes the structure of what you want to match โ any digit, any word character, any sequence of 2 to 5 letters, a word that starts with capital letters, and so on. The replacement can then reference parts of what was matched and rearrange or transform them.
The result is a tool that can do in one operation what would take hours of manual editing โ or be impossible manually at all.
Example: Convert dates from DD/MM/YYYY to YYYY-MM-DD
Find: (\d{2})/(\d{2})/(\d{4})
Replace: $3-$2-$1
Input: "Invoice dated 15/03/2024 due 30/04/2024"
Output: "Invoice dated 2024-03-15 due 2024-04-30"2. The Five Regex Concepts You Actually Need
Regex has a reputation for complexity. Much of that reputation is earned โ full regex syntax is enormous. But for find and replace tasks, you only need five things:
1. Character classes โ what to match
\d โ any digit (0โ9) \w โ any word character (a-z, A-Z, 0-9, _) \s โ any whitespace (space, tab, newline) . โ any character except newline [aeiou] โ any vowel [^aeiou] โ anything that is NOT a vowel
Character classes describe a set of characters to match at a single position.
2. Quantifiers โ how many to match
* โ zero or more
+ โ one or more
? โ zero or one (optional)
{3} โ exactly 3
{2,5} โ between 2 and 5Quantifiers control how many of the preceding element must appear. By default they are greedy โ they match as much as possible.
3. Anchors โ where to match
^ โ start of string (or line with m flag) $ โ end of string (or line with m flag) \b โ word boundary
Anchors match a position rather than a character. They constrain where in the string the pattern can match.
4. Groups โ capture and reference
(pattern) โ capture group โ reference as $1, $2 (?:pattern) โ non-capture group โ groups but doesn't capture (?<name>pattern) โ named group โ reference as $<name>
Groups are the key to powerful replacements. What is captured in groups can be referenced and rearranged in the replacement string.
5. Flags โ how to match
g โ global (replace all, not just first) i โ case insensitive m โ multiline (^ and $ match line boundaries) s โ dotAll (dot matches newline too)
Flags modify the overall behaviour of the regex. The g flag is almost always what you need for find-and-replace work.
3. Capture Groups: The Most Powerful Replacement Feature
Capture groups transform regex find-and-replace from a search tool into a transformation engine. Without capture groups, you can find and delete or find and overwrite. With capture groups, you can find, extract, rearrange, and reconstruct.
Every set of parentheses in your pattern creates a capture group. The first opening parenthesis creates group 1, the second creates group 2, and so on. In your replacement string, $1 inserts whatever was captured by group 1, $2 inserts group 2, and so on.
Swap first and last name
Find
(\w+),\s*(\w+)Replace
$2 $1"Doe, John" โ "John Doe"
Convert function style
Find
get_(\w+)Replace
fetch$1"get_user" โ "fetchuser" (add capital: fetchUser needs more)
Wrap matched text in HTML
Find
(\d+\.\d+)Replace
<strong>$1</strong>"Price: 19.99" โ "Price: <strong>19.99</strong>"
Reformat phone numbers
Find
(\d{3})[-.](\d{3})[-.](\d{4})Replace
($1) $2-$3"555-123-4567" โ "(555) 123-4567"
4. Real-World Examples with Full Patterns
Remove all HTML tags
Find
<[^>]+>Replace
(empty)Flags
gUseful when copy-pasting from web pages or cleaning HTML exports. The pattern [^>]+ matches any character except > one or more times.
Convert camelCase to snake_case
Find
([a-z])([A-Z])Replace
$1_$2Flags
gInsert an underscore between a lowercase letter followed by an uppercase letter. Apply the result a second time and then use a lowercase transformation to complete the conversion.
Redact email addresses
Find
[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}Replace
[EMAIL]Flags
giReplace all email addresses with a placeholder. The i flag makes it case-insensitive for the domain part.
Remove duplicate spaces
Find
+Replace
Flags
gCollapse any sequence of two or more spaces into a single space. Simple but one of the most-used cleanup patterns.
Wrap each line in double quotes
Find
^(.+)$Replace
"$1"Flags
gmThe m flag makes ^ and $ match line boundaries. Combined with g, this runs on every line. Perfect for preparing lists for CSV or code use.
Remove blank lines
Find
^\s*$\nReplace
(empty)Flags
gmMatch lines that contain only whitespace (or nothing at all) and delete them including their newline character.
5. Multi-Step Replacement Workflows
Some transformations are too complex for a single regex. The output of one replacement becomes the input of the next โ this is multi-step or pipeline replacement. Our tool supports this natively with multi-rule mode.
A common example is converting camelCase to Title Case. One regex step inserts spaces before capitals. A second step capitalizes the first letter. A third step cleans up any double spaces. Each step is simple; together they achieve something complex.
Example: Convert snake_case to Title Case
Replace underscores with spaces
Find: _ โ Replace: Capitalize first letter of each word (JS: use toUpperCase in code)
Find: \b(\w) โ Replace: \u$16. Regex Find and Replace in Different Tools
The core regex syntax is consistent, but replacement syntax and flags differ between environments. Here is a quick reference:
| Tool | Capture group ref | Case modifier | Notes |
|---|---|---|---|
| JavaScript | $1, $2 | None (use JS code) | str.replace(regex, '$1') or function |
| Python re | \1, \2 or \g<1> | None (use .upper() etc.) | re.sub(pattern, replacement, string) |
| VS Code | $1, $2 | \u$1 (uppercase), \l$1 (lower) | Ctrl+H โ check Use Regular Expressions |
| sed (Linux) | \1, \2 | None natively | sed 's/find/replace/g' file |
| Vim | \1, \2 | \u\1 (upper), \l\1 (lower) | :%s/find/replace/g |
| This tool | $1, $2, $<name> | N/A | Supports g, i, m, s flags |
7. Common Mistakes and How to Avoid Them
โ Forgetting the g flag
Without g, the replacement only applies to the first match. If you expected all matches to change but only the first did, add g to your flags.
โ Fix: Add "g" to the flags field.
โ Unescaped special characters
A dot (.) in regex matches any character. If you want to match a literal dot โ in a URL or file extension โ you must escape it: \. Without escaping, "file.txt" pattern would match "filetxt", "file1txt" and so on.
โ Fix: Escape special characters: \. \* \+ \? \( \) \[ \] \{ \} \^
โ Greedy quantifiers matching too much
The pattern <.+> is intended to match one HTML tag. But + is greedy and will match from the first < to the last > on the line, consuming everything in between including other tags.
โ Fix: Use [^>]+ instead: <[^>]+>. Or use a lazy quantifier: <.+?>
โ Wrong capture group numbering
Groups are numbered from left to right by their opening parenthesis. Non-capturing groups (?:...) do not get a number. Getting the count wrong means $1 pulls the wrong content.
โ Fix: Test your pattern in the tool's match view to see exactly what each group captures before writing the replacement.
โ Not using the m flag for line-based work
Without m, ^ only matches the very start of the string and $ only matches the very end. If you are trying to match the start or end of each line, you need the m flag.
โ Fix: Add "m" to the flags field whenever your pattern uses ^ or $ to mean line boundaries.
8. When NOT to Use Regex
Regex is powerful but it has genuine limits. Knowing when not to use it saves time and prevents bugs.
๐ซ Parsing HTML or XML
HTML is not a regular language. Regex cannot handle nested tags reliably. Use a proper HTML parser like BeautifulSoup or the browser DOM.
๐ซ Parsing JSON
JSON structure is recursive and regex cannot handle arbitrary nesting. Use JSON.parse() or equivalent. Regex can find simple values in JSON but fails on complex structures.
โ ๏ธ Validating email addresses definitively
The full RFC 5322 email standard cannot be fully expressed in a practical regex. Use a library or send a confirmation email to verify.
โ ๏ธ When a simple string operation works
If you are replacing one fixed word with another, str.replace() without regex is clearer and faster. Regex has overhead and is harder to read.
9. FAQ
What is $& in a replacement string?
$& inserts the entire matched string. For example find (\d+) and replace with [$&] puts brackets around every number without needing a capture group.
How do I replace only the second occurrence of a match?
Standard regex doesn't have an 'Nth occurrence' feature. Options: use a counter in code, use a lazy quantifier to skip earlier matches, or run two separate replacements where the first marks the second occurrence.
Why does my replacement add extra backslashes?
In replacement strings, $ and \ are special. A literal $ must be written as $$. A literal backslash must be written as \\. This is a common source of confusion when replacement strings look different from what you expect.
Can I do a case-insensitive find but case-sensitive replace?
Yes. The i flag only affects matching. The replacement is always applied literally. So /hello/gi finds Hello, HELLO, and hello but replaces them all with exactly what you write in the replacement field.
How do I reference a named capture group?
Name a group with (?<name>pattern) and reference it in the replacement with $<name>. For example find (?<year>\d{4})-(?<month>\d{2}) and replace with $<month>/$<year>.
Ready to Try It?
Full regex find and replace in your browser โ capture groups, diff view, 20+ presets. Free, no login.
Open Regex Find and Replace