Skip to main content

Find & Replace

Find and replace text with regex support and case-sensitive options.

Reviewed by · Last reviewed

How to Use the Find and Replace Tool

  1. Paste your source text into the large input area. Any size up to several megabytes is handled without a round trip to a server.
  2. Type what you want to find in the Find field. For literal text this is just the phrase; for pattern matching, enable Regex mode first.
  3. Type the replacement in the Replace field. You can use $1, $2, $<name>, $&, and friends when Regex mode is on.
  4. Toggle options depending on your intent: Case-sensitive turns matching into an exact-character comparison, Whole word adds word-boundary anchors, Regex mode interprets the Find field as a JavaScript regular expression.
  5. Click Replace All. The result panel populates below along with a count of replacements performed.
  6. Copy the result with the Copy button, or iterate by tweaking the Find or Replace fields and clicking Replace All again on the updated input.

What the Tool Does Under the Hood

In literal mode the Find string is escaped using a helper that prefixes every regex metacharacter (.\\+*?[](){}^$|) with a backslash, then compiled into a RegExp with the g flag - optionally i for case-insensitive - and passed to String.prototype.replaceAll (or replace with the global flag on older browsers). Whole-word mode wraps the escaped string in \\b...\\b anchors. Regex mode skips the escaping step entirely and compiles the Find field as-is, so you get full access to alternation, capture groups, lookarounds, and Unicode property escapes. The replacement string is processed by JavaScript's built-in replace semantics, which means $1 through $99 refer to numbered capture groups, $<name> refers to named groups, $& is the whole match, and $$ escapes a literal dollar sign. No text ever leaves the tab.

When You Would Use It

  • Renaming a function or variable in a code snippet you pulled out of a larger file for review.
  • Fixing a brand capitalization mistake across a blog post that quotes the name dozens of times.
  • Converting Markdown to HTML-ish quickly: turn **bold** into <b>$1</b> with regex \\*\\*(.+?)\\*\\*.
  • Reformatting CSV-like data by replacing commas with tabs or swapping column order via capture-group rearrangement.
  • Redacting PII before sharing a log file: regex-replace /\\d{3}-\\d{2}-\\d{4}/g with XXX-XX-XXXX.
  • Cleaning up translation files where every occurrence of a legacy product name needs to become the new one, but only when it appears as a whole word.

Common Pitfalls and Edge Cases

  • Literal dollar signs. In replacement text, $ is special. To insert a literal $ use $$. Paste-and-pray replacement into code with price formatting often catches this.
  • Unescaped regex metacharacters in literal mode. The tool escapes them for you, but if you switch to Regex mode mid-session without thinking, suddenly a parenthesis means capture group rather than literal paren.
  • Greedy vs lazy quantifiers. <.+> against <a>...</a> captures the whole line because .+ is greedy; use <.+?> for the expected per-tag behavior.
  • Whole word on non-Latin scripts. \\b is ASCII-centric - it finds boundaries between word characters ([A-Za-z0-9_]) and non-word characters. For CJK or Arabic text, word boundaries are not well defined and the option may behave surprisingly.
  • Multi-line matches. The dot does not match newlines unless you enable dotAll via (?s) in newer engines or add the s flag in Regex mode. A pattern like foo.*bar will not match across line breaks without it.
  • Catastrophic backtracking. Nested quantifiers such as (a+)+ applied to long non-matching input can freeze the tab. If Replace All hangs, your regex is the culprit.

Regex Replacement Background

JavaScript's replace method was standardized in ECMA-262 back in 1997 and has barely changed since. The replacement-string syntax - $n for groups, $& for match, $' and $` for suffix and prefix - traces back to Perl 4. sed uses \\1 through \\9 for the same purpose, which is why porting a regex between shell and JavaScript often requires adjusting backreferences. Named capture groups are a modern addition (ES2018) that make patterns self-documenting: (?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2}) replaced with $<day>/$<month>/$<year> reorders dates without ambiguity. PCRE supports \\g<name> and (?P=name) for similar effects; Python's re module uses \\g<name>.

Comparison to Alternatives

sed -E 's/foo/bar/g' file is the Unix workhorse for the same job - fast, scriptable, and POSIX-standard, though sed's regex dialect is subtly different from JavaScript's (no lookaheads in basic mode, different backreference syntax). perl -pe gives full Perl regex and inline editing and is what many bash scripts actually reach for when sed's ERE mode is not enough. Your IDE's Find-in-files is usually the right tool for cross-file replacement because it shows a preview and offers undo. ripgrep --replace and sd are fast Rust-based replacements for sed on modern systems. Use this web tool for a single-snippet, one-off change where you want instant visual feedback, capture-group playground semantics, and zero install - especially handy on a Chromebook, a phone, or a locked-down corporate machine.

Frequently Asked Questions

What is the exact regex dialect?

ECMAScript, as defined in ECMA-262. That means JavaScript-flavor regex: \w is [A-Za-z0-9_], dot does not match newline by default, named groups use (?&lt;name&gt;...), and the u flag unlocks Unicode property escapes like \p{Letter}. It differs from PCRE in several places: no possessive quantifiers, no atomic groups, no inline modifiers (?i), and no regex recursion. Patterns valid in PHP or Python may need tweaking; patterns valid in Node.js or your browser code work here unchanged.

How do I insert a literal dollar sign in the replacement?

Type $$ and the engine will insert a single $ in the output. The first $ is an escape character in ECMAScript replacement syntax, so $5.00 would try to reference capture group 5 which usually does not exist and results in literal $5.00 in some engines or an empty match in others. Using $$5.00 is unambiguous and correct everywhere.

Does the tool process my text on a server?

No. The replace operation is a synchronous JavaScript call that runs inside the page. No fetch, no worker, no analytics beacon carrying the text. The RegExp constructor and String.replaceAll method are both native to your browser engine - V8, SpiderMonkey, or JavaScriptCore - and have no network dependencies. You can verify by watching the Network panel in DevTools while you click Replace All.

Why is Whole word not matching my CJK text?

Because \b - the word boundary anchor in ECMAScript - is defined as a position between a \w character and a non-\w character, where \w is strictly [A-Za-z0-9_]. Japanese, Chinese, Korean, Arabic, Thai, and most scripts other than Latin or Cyrillic do not participate in \w, so there is no boundary to anchor to. For CJK segmentation you need a proper tokenizer (Intl.Segmenter in modern browsers, or a dictionary-based library like kuromoji).

Can I do a multi-line capture-group replacement?

Yes. Enable Regex mode, write your pattern across the multi-line boundary using explicit \n or the s flag to let dot match newlines, and use capture groups as normal. For example converting HTML to Markdown-ish lists: &lt;li&gt;([\s\S]+?)&lt;/li&gt; with replacement - $1 works. Note that [\s\S] is the classic idiom for &quot;any character including newline&quot; that predates the s flag and still works everywhere.

What happens when my regex is invalid?

The RegExp constructor throws a SyntaxError with a descriptive message (&quot;Unterminated group&quot;, &quot;Invalid escape&quot;, etc.). The tool catches it, displays the error next to the Find field, and leaves the input unchanged. Fix the pattern and click Replace All again. Because there is no silent failure, you do not have to wonder whether a broken regex wiped out your input.

Does this handle very large inputs?

Inputs up to several megabytes of text are fine; the bottleneck is the textarea UI rather than the regex engine. Once you pass around 10 MB, browsers start struggling to render, and regex operations with high-complexity patterns can take seconds or hang the tab with catastrophic backtracking. For log-file-sized input use sed, perl, or ripgrep --replace on the terminal.

How do I preview changes before committing?

The tool does not have a separate preview mode - the output panel is the preview, and the original input stays in the Find area unchanged until you copy out. If you want to diff before and after, paste the result into the Diff Checker tool on this site and compare against the original. That is often more informative than a numeric replacement count.

Is there an undo?

The tool itself does not maintain a history, but Replace All is non-destructive: it reads the input and writes the result to a separate output panel, leaving the source text intact in the input textarea. You can switch options and click Replace All repeatedly against the same source without losing it. If you paste the output back into the source, your browser&apos;s Ctrl+Z usually works within the textarea to step backward.

Can I use Unicode categories like letters-only?

Yes. In Regex mode, set the u flag and use \p{L} for any letter, \p{N} for any number, \p{Punctuation} for punctuation, and so on as defined by Unicode Standard Annex #44. For example, to strip all non-letters from a line: /[^\p{L}\s]/gu replaced with an empty string. This is the modern, portable way to write culture-aware patterns.

More Text Tools