Find & Replace
Plain or regex find-and-replace with capture-group backreferences
How to Find & Replace Online
Find and replace text with optional regex support and capture-group backreferences.
- Paste your text into the input box.
- Type what you want to find in the Find field. Toggle 'Regex' if you need pattern matching.
- Type the replacement in the Replace field. In regex mode, use $1, $2 for capture groups and $& for the whole match.
- Adjust the toggles: Case sensitive (default on), Whole word (plain mode only), Multiline and Dotall (regex mode).
- The output panel updates live with the replaced text and a count of how many replacements happened.
- Click Copy to put the result on your clipboard.
About Find & Replace
Find-and-replace is the oldest user-facing computing operation that still matters every day. Every editor, IDE, word processor, and command-line tool ships a flavor of it. The hard part is rarely the typing — it is reaching for the *right* flavor for the task. Naive string replacement is fast and predictable, regex replacement is powerful but easy to footgun, and the difference between matching a literal "function" and matching the regex pattern "function" is a single backslash that can quietly corrupt a thousand lines of code if you get it wrong.
This tool gives you both modes with explicit toggles and live preview. **Plain mode** is the literal-string match — what you type is what gets matched, with no interpretation of regex metacharacters. Plain mode is what you want for finding "if (foo === undefined)" or "TODO:" or any other string with predictable content. **Regex mode** unlocks the full ECMAScript regex engine — character classes, quantifiers, anchors, lookarounds, capture groups, the whole language. Crucially, the replacement string in regex mode supports **backreferences**: `$1` refers to the first capture group, `$2` to the second, `$&` to the entire match. This is the same syntax `String.prototype.replace` uses and the same syntax `sed` uses (with backslash escapes instead of dollar signs).
A small ergonomic choice worth knowing: the **Whole word** toggle is plain-mode-only. In plain mode it wraps your search term in `\b...\b` after regex-escaping it, which means searching for "id" will match "id" but not "fluid" or "kids". In regex mode you have full `\b` control yourself, so the toggle is hidden — adding it would either fight your pattern or duplicate `\b`s you may already have. **Multiline** and **Dotall** are independent regex flags: multiline (`m`) makes `^` and `$` match line boundaries, dotall (`s`) makes `.` match newlines. They show up only in regex mode because they have no meaning without a regex.
The live preview is the design feature that makes this faster than reaching for a text editor's find-replace dialog. Every keystroke recomputes the result, the replacement count, and any pattern errors. You can iterate on a tricky regex by watching the output change in real time, and the cost of typing one extra character is zero — no Find Next, no Replace All button, no confirmation dialog. The output is read-only until you copy it, so you cannot accidentally clobber your input.
A few practical patterns worth knowing:
- **Strip surrounding quotes**: search `^"(.*)"$` (regex, multiline), replace with `$1`. - **Reformat email lists**: search `(\w+)@(\w+\.\w+)` (regex), replace with `<a href="mailto:$&">$1</a>`. - **Add a prefix to every line**: search `^` (regex, multiline), replace with `PREFIX: `. - **Remove trailing whitespace**: search `[ \t]+$` (regex, multiline), replace with `` (empty).
The implementation is a thin wrapper over native JavaScript. The pattern compiles via `new RegExp(pattern, flags)`. The replacement runs through `String.prototype.replace`, which is the part that gives you backreferences "for free" without writing them yourself. Match counts use a second pass with the same regex and a counter callback — this is necessary because the static replace path doesn't return the count, only the modified string. Two passes is still O(N) and runs in microseconds for typical inputs.
Everything happens in your browser. The page makes zero network requests during the replace operation. Pasting source code, log files with internal hostnames, or proprietary content is safe — the pattern and the text never leave your tab. For very large inputs (multi-megabyte logs) the algorithm is still linear, but the React re-render of an enormous output may feel laggy; for those cases the command-line `sed` is faster.
Related Tools
Frequently Asked Questions
When should I enable regex mode?
Whenever the thing you want to find is not a single literal string. Examples: 'every email address in this log file', 'every Markdown link', 'every TODO comment but only at the start of a line'. Plain mode treats your search string as a literal — it cannot match patterns. Regex mode lets you use `.`, `*`, `+`, character classes, anchors (`^`, `$`), and capture groups. Match counts and replacement happen identically; only the matching is more powerful.
What do $1, $2, and $& do in the replacement string?
They are backreferences to captured groups. In a pattern like `(\w+)@(\w+\.\w+)`, `$1` is the username portion of every email match and `$2` is the domain. `$&` is the entire match. So `(\w+)@(\w+\.\w+)` → `$1 at $2` rewrites `alice@example.com` to `alice at example.com`. This is the same syntax used by `String.prototype.replace` in JavaScript and by `sed`'s `\1` / `\2` (with a different escape character).
Why is 'Whole word' disabled in regex mode?
Because regex mode lets you express word boundaries explicitly with `\b`. The 'Whole word' checkbox in plain mode is a shortcut that wraps your search in `\b...\b` after escaping it. In regex mode you have full control — add `\b` yourself where you want it, and skip it where you do not. This avoids the confusing case where 'Whole word' would apply word boundaries to a pattern that already has its own.
What is the difference between multiline and dotall?
Two different flags doing different things. **Multiline** (`m`) changes the meaning of `^` and `$` — without it, they match only the start and end of the whole string; with it, they match the start and end of every line. **Dotall** (`s`) changes `.` — without it, `.` matches any character except a newline; with it, `.` matches newlines too. They are independent — you can enable either, both, or neither.
Can I replace with a function (callback)?
Not in this tool — that would require executing arbitrary JavaScript from the page, which would be a security hazard. For function-based replacement (different output per match based on the matched content), use JavaScript directly: `input.replace(re, (m, g1) => doSomething(g1))`. For straightforward case-flipping or formatting changes, the Case Converter tool (linked below) might be a better fit.
Is the operation case-sensitive by default?
Yes, the 'Case sensitive' checkbox is on by default. This matches how `String.prototype.replace` works without the `i` flag and how most code-aware editors (VS Code, Sublime) default. Toggle it off when you want `Email` and `email` and `EMAIL` to all match the same search term.
Is any input sent to a server?
No. The pattern is compiled with `new RegExp` and applied with `String.prototype.replace` — both browser built-ins. Zero network requests. Pasting source code, log files, internal docs is safe.