Independent writing tools and guides, edited by a human

Find and Replace

Search and replace across large texts with plain or regex matching, case control, live match count, and a highlighted preview.

Your workbench
0 characters
Read-only
Ready when you are.
On this page (08)
  1. 01Two kinds of find
  2. 02How a literal search behaves
  3. 03What regular expression mode turns on
  4. 04The match count is your safety net
  5. 05Whole words, and the cat inside category
  6. 06What the pattern engine will not do for you
  7. 07Frequently Asked Questions
  8. 08Read the match count, then run it

Two kinds of find

Most of the time you want to swap one string for another: rename a character, correct a client's name, change "colour" to "color". Occasionally you want to replace a shape: every date, every number, every doubled space. Those are different jobs, and one checkbox separates them.

Literal matching is the default; regular expression mode is opt-in and changes how both boxes are read.

How a literal search behaves

Type a phrase and every occurrence changes at once. There is no replace-one-at-a-time button, so the safety comes from the two boxes being separate: the original stays in its field and the result appears beside it.

Three behaviours surprise people.

Matching ignores case by default. Tick "Match case" to narrow it. Searching draft without the tick also rewrites Draft at the start of a sentence, and DRAFT in a heading.

Special characters are literal. A search for a.b finds a.b, not axb, because the period is escaped for you. So are asterisks, brackets, and backslashes.

An empty Replace box deletes. To remove text rather than change it, leave the replacement empty.

The replacement is inserted exactly as typed, so $1 in literal mode inserts the characters $1.

What regular expression mode turns on

With the checkbox ticked, the Find box is compiled as a pattern. . becomes any character, \d a digit, [aeiou] a vowel, \s whitespace, and parentheses capture, returning in the replacement as $1, $2, and so on.

In the Replace boxLiteral modeRegular expression mode
$1The characters $1The first captured group
$$Two dollar signsOne literal dollar sign
\nA backslash and an nA backslash and an n

There are no escape sequences in the replacement box, so you cannot type a line break into it. To write a price of $1.99 into every match, the replacement has to be $$1.99.

In regex mode, ., *, +, ?, (, ), [, ], {, }, |, ^, $, and \ all do something, so a literal one needs a backslash. A forward slash is ordinary, because the pattern is built from a string rather than a regex literal.

This is the mode that rebuilds a table from a PDF paste: a run of spaces replaced by a comma turns aligned columns into something a spreadsheet accepts, which the remove extra spaces tool cannot do.

The match count is your safety net

Every run reports three numbers: Matches, Input characters, and Output characters. Read the first before you read the result.

The count is the number of replacements that will happen, not an estimate. If it says 47, you are about to make 47 changes; if you expected four, the pattern is wrong and you know before you commit. It updates as you type, so widening a pattern and watching the count climb is the whole method.

Matches never overlap. In aaa, the pattern aa matches once, at the first two characters. Replacing it with X gives Xa.

Inserted text is not re-scanned. A replacement containing the search term does not cascade, because the browser scans the original text in one left-to-right pass. Replacing draft with draft note adds one note per original match. The cascade arrives when you copy the output back in and run it again.

Whole words, and the cat inside category

There is no whole-word checkbox, so a plain search for cat also hits category, concatenate, and vacation. In a document about pets, that is a mess.

Regex mode gives you the tool for it: \bcat\b. The \b is a word boundary, matching the position between a word character and a non-word character without consuming anything, so the animal is found and category is left alone.

The same logic explains why bulk edits of easily confused words deserve suspicion. Replacing its with it's looks efficient and is not, because the two are not interchangeable. The confusing word pairs that cause the most damage are the ones where both spellings are real words.

What the pattern engine will not do for you

The pattern is compiled with two settings: always global, and case-insensitive unless Match case is ticked. There is no flag control, which has consequences.

You might wantWhy it does not work hereWhat to do instead
^ at the start of every lineNo multiline flag, so ^ means the start of the whole textMatch a newline explicitly
. to cross a line breakNo dot-all flag, so . stops at a newlinePut \n in the pattern
. to match one emojiNo Unicode flag, so . is one UTF-16 unit and can split an emojiMatch the surrounding text
\w to include accented lettersNo Unicode flag, so \w excludes accented lettersWrite an explicit character class

An invalid pattern surfaces the browser's own error message, which quotes the compiled pattern and names the fault in the engine's words rather than the tool's. If nothing changes and the status line mentions a regular expression, check unbalanced brackets and unescaped . or *. Each field also accepts up to 200,000 characters.

When a pattern runs away

Some patterns are correct and ruinously slow. Nested quantifiers are the usual culprits: (a+)+, (.*)*, (\s*)*. Against a long string that almost matches, the engine must try exponentially many ways to divide the text before concluding there is no match.

This is why the work runs in a separate worker with a four-second limit. A bad pattern does not freeze the page: the worker is stopped, the run abandoned, and the status line says the processing took too long and was stopped safely.

Two habits keep you out of that corner: anchor the pattern to a known word, and prefer a negated class such as [^"]* to .*, which cannot backtrack into itself the way a greedy wildcard can.

Frequently Asked Questions

Why did my replacement change Draft as well as draft?

Because matching ignores case unless you tick Match case. That default catches sentence-initial capitals, and headings set in capitals along with them.

How do I replace a whole word without touching words that contain it?

Turn on Regular expression mode and wrap the word in \b on both sides: \bcat\b. There is no whole-word checkbox, so the markers are the substitute.

What does $1 do, and when do I need $$?

Only regex mode reads $1 as a captured group. In literal mode those characters are inserted as typed. For a literal dollar sign in regex mode, double it: $$1.99 gives $1.99.

Why did my pattern stop with a message about taking too long?

Because it backtracked. Nested quantifiers can need an exponential number of steps on text that nearly matches, and the worker is stopped after four seconds.

Why does a search for a.b not find axb?

Because literal mode is the default and special characters are escaped for you. Tick Regular expression mode to make the period a wildcard.

Read the match count, then run it

Before you run anything wide, look at the number of matches. It takes a second, and it is the difference between a rename and a small catastrophe: a pattern one character too loose will rewrite a word you never meant to touch. If the count matches your expectation, run it. If not, tighten the pattern, not the text.