Multi Find and Replace

Rules run top to bottom and each one sees the output of the one above it, which is why A => B followed by B => C turns your original A into C. That ordering is the whole behaviour worth understanding here; the per-rule hit counts below the result tell you whether a rule did anything at all.

An empty right-hand side deletes the match. In regex mode $1, $2 and $& are available in the replacement.
Multi Find and Replace — Apply Many Search-and-Replace Rules in One PassBuildFigure

Writing the rules

One rule per line, in the form find => replace. Leave the right-hand side empty and every match is deleted. By default the spaces on either side of the arrow are trimmed, so you can write the rules with breathing room. Turn trimming off when the space itself is part of what you are matching or inserting — replacing a double space with a single one needs trimming off, otherwise both sides collapse to nothing and the rule is skipped.

The first => on the line is the separator, which means the find side cannot itself contain an arrow. That is the one input this tool cannot express.

Order is the feature, not a side effect

Each rule runs against the output of the rules above it. Two consequences follow, and both bite people the first time.

Rules, in orderInputOutput
A => B then B => CA BC C
B => A then A => BA BB B
A => @@T@@, B => A, @@T@@ => BA BB A

Swapping two values requires the third form: park one of them on a placeholder that cannot occur in the text, move the other, then unpark. The related habit is to put longer strings before the shorter strings contained inside them, so that customer id is handled before a bare id rule reaches it.

Regex mode

With regex on, the find side is compiled as a JavaScript regular expression and the replacement side understands $1 through $9 for capture groups and $& for the whole match. (\d{4})-(\d{2})-(\d{2}) => $3/$2/$1 flips ISO dates into day-first order. A pattern that fails to compile is reported against its rule number and skipped; the remaining rules still run.

With regex off, every character on the find side is literal. A find side of . matches a full stop and nothing else, and (1) matches those three characters. You do not need to escape anything.

Whole words, and what that means outside English

Whole-word matching only replaces when the match is not flanked by a letter, digit or underscore, so a rule for cat leaves category alone. Where the browser supports Unicode property escapes, the boundary test covers letters in any script rather than just ASCII, so an accented or Cyrillic letter next to the match also blocks it.

The option is close to useless for scripts that do not put spaces between words. Chinese, Japanese and Korean text runs characters together, and Korean in particular glues grammatical particles onto the end of nouns, so the noun you are looking for is almost never at a word boundary. For those inputs leave whole-word matching off and rely on longer, more specific find strings instead.

Input is capped at 300,000 characters and the tool says so rather than freezing. Everything happens in the page — the text is never sent anywhere, which is the point when the thing you are bulk-editing is a contract draft or a customer export.

Questions people ask

How do I search for the "=>" characters themselves?

You cannot, because the first arrow on the line is what separates the two halves of the rule. Escaping it in regex mode does not help — the line is split before the pattern is ever compiled. Work around it by replacing the two characters separately, or by replacing a longer string that contains the arrow, such as the surrounding words.

Can I replace line breaks?

On the find side, yes: turn on regex mode and match \n, so a rule of \n{3,} => \n\n collapses runs of blank lines. The replacement side is literal text, so \n there inserts a backslash and an n rather than a newline. To insert a real line break, put the break in a captured group and reference it, or split the job into two passes using a placeholder string that you then replace by hand.

A rule reports zero hits but I can see the text right there.

Three causes account for almost all of these. Case: turn on "ignore case". Invisible characters: text pasted out of a word processor or a web page often carries non-breaking spaces (U+00A0), narrow no-break spaces, or curly quotes that look identical to the straight ones you typed. Whole-word matching: it is on and the match is touching a letter or digit. The reliable fix is to copy the string out of the input box itself and paste it into the rule rather than retyping it.

Does the replacement side of one rule get re-processed by later rules?

Yes. There is one working copy of the text and each rule rewrites it in turn, so anything a rule inserts is visible to every rule below. That is exactly why placeholder strings for swaps need to be improbable — if you park a value on the string TEMP and a later rule happens to touch TEMP, the swap corrupts. Use something like @@T1@@ that will not occur naturally.

Related