Skip to main content
HomeBlogRegex Find & Replace Guide
RegexDeveloper ToolsText Processing

Regex Find and Replace: The Complete Practical Guide for Developers and Writers

A thorough, example-driven guide to regex find and replace โ€” from beginner patterns to advanced capture group techniques, real-world use cases, and the exact syntax differences between JavaScript, Python, sed and VS Code.

QuickTextTools Team
15 min read
Updated 2025

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

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 5

Quantifiers 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

g

Useful 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_$2

Flags

g

Insert 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

gi

Replace all email addresses with a placeholder. The i flag makes it case-insensitive for the domain part.

Remove duplicate spaces

Find

+

Replace

Flags

g

Collapse 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

gm

The 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*$\n

Replace

(empty)

Flags

gm

Match 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

1

Replace underscores with spaces

Find: _ โ†’ Replace:
2

Capitalize first letter of each word (JS: use toUpperCase in code)

Find: \b(\w) โ†’ Replace: \u$1

6. 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:

ToolCapture group refCase modifierNotes
JavaScript$1, $2None (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, \2None nativelysed 's/find/replace/g' file
Vim\1, \2\u\1 (upper), \l\1 (lower):%s/find/replace/g
This tool$1, $2, $<name>N/ASupports 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