Regex find and replace, online
Write a pattern and a replacement, and read the rewritten text back live. The replacement
understands $1, $<name>, $&,
$` and $'.
Regular expression find and replace
JavaScript syntax. Write the pattern only — no surrounding slashes. Just matching, not replacing? Use the regex tester.
$1…$n insert a group, $<name> a named group,
$& the whole match, $$ a literal dollar. This is JavaScript, so
it is $1, never \1.
/(?:)/g The replacement vocabulary
A regex replacement is not another pattern — it is a template, and every special sequence in
it starts with a dollar sign. These are the ones JavaScript's String.replace
understands, which is exactly the set this page accepts:
| Token | Inserts |
|---|---|
$1…$99 | The text captured by that numbered group. $1 is the first (...) in the pattern. |
$<name> | The text captured by a named group written (?<name>...). |
$& | The whole matched substring, groups or not. |
$` | Everything in the subject before the match. |
$' | Everything in the subject after the match. |
$$ | A single literal dollar sign. |
A reference to a group that does not exist — $3 when the pattern has two groups,
or $<day> when nothing is named day — is reported as an error
here. Plain String.replace would quietly leave it in the output as literal text,
which is a subtle way to ship a wrong string, so this page refuses it instead.
The one that trips everyone up: \1 versus $1
If you learned regular expressions in sed, Perl, Vim, or almost any PCRE-based
tool, a backreference in the replacement is \1. In JavaScript it is
$1. This is the single most common find-and-replace mistake, because the pattern
side of both flavours looks nearly identical — it is only the replacement that diverges.
Type \1 here and you get the literal characters backslash-one in your output,
not the captured group.
The confusion runs the other way too: inside the pattern, JavaScript does use
\1 as a backreference — (\w)\1 matches a doubled letter. So the
same tool wants \1 in the pattern and $1 in the replacement. Keep
the rule simple: backslash to match a repeat, dollar to write a capture.
Greedy and lazy change what gets replaced
Greediness is a matching property, but it decides the shape of every replacement, because a
replacement can only substitute what a match actually covered. Quantifiers are greedy by
default: <.+> against <a><b> matches the entire
string, so replacing it with [$&] yields one bracketed blob rather than two
tags. Add a ? to make the quantifier lazy — <.+?> stops at the
first > — and with the global flag the replacement fires once per tag. When a
find-and-replace does too much or too little, greediness is the first thing to check.
Why it will not freeze the tab
The substitution runs on the page's main thread, so a pathological pattern is a frozen tab
rather than a slow one. A pattern like (a+)+$ against a long line that does not
match backtracks catastrophically — the engine tries an exponential number of ways to split
the string before giving up. Replacing is therefore capped at 1,000 matches and 250
milliseconds; hit either and the count line says so, and any text past the cap is left exactly
as it was rather than partly rewritten. The regex tester applies the same two
ceilings when you are only matching.
Common questions
Why doesn't \1 work in the replacement?
Because this is JavaScript, and JavaScript names a captured group in a replacement with $1, not \1. The backslash form is what sed, Perl, and most PCRE-based tools use, which is why people reach for it out of habit. Here \1 is passed through as the literal two characters backslash-one; write $1 for the first group, $2 for the second, and so on.
How do I reuse a named group in the replacement?
With $<name>, matching the (?<name>...) syntax you used to capture it. So a pattern of (?<year>\d{4})-(?<month>\d{2}) with a replacement of $<month>/$<year> swaps the two. A named group can still be reached by its position too — it counts in the numbering — so $1 and $<year> refer to the same text when year is the first group.
What do $&, $` and $' mean?
They are the whole match and the text around it. $& is the entire matched substring, $` (backtick) is everything before the match, and $' (apostrophe) is everything after it. They are the pieces String.replace exposes beyond the numbered groups, useful for wrapping a match — a replacement of [$&] brackets whatever matched without needing a capture group around the pattern.
Why did my replacement swallow more text than I expected?
Quantifiers are greedy: <.+> against <a> and <b> matches from the first < to the last >, so replacing it with one thing eats both tags and the words between them. Add a ? to make the quantifier lazy — <.+?> stops at the first > — and the replacement runs once per tag instead of once for the whole line. Greediness changes what each match covers, which is exactly what the replacement then substitutes.
Why did replacing stop before the end of my text?
Replacing is capped at 1,000 matches and 250 milliseconds, and the count line says so when a cap is hit. Some patterns backtrack catastrophically — nested quantifiers such as (a+)+ against a long non-matching string are the classic case — and because this runs on the page's main thread, an uncapped run would freeze the tab rather than merely be slow. Text past the cap is left untouched rather than half-processed.
Is my text uploaded anywhere?
No. The pattern, the replacement, and the subject all stay in your browser, and the substitution runs locally with the same engine that powers String.replace. Nothing is sent to a server, logged, or stored, and the page keeps working offline once loaded.