induwara.lk
induwara.lkText · Developer

Find and Replace — Bulk Text Replace with Regex

Search and replace inside any text — plain or regex, case-sensitive or insensitive, whole-word or substring, single rule or a chained pipeline. Live match counts, Unicode-aware boundaries, every keystroke processed locally in your browser.

By Induwara AshinsanaUpdated May 11, 2026
Find and replacePlain, regex & multi-rule
Runs entirely in your browser. Nothing is uploaded, logged, or stored.
Matches found
0
Replacements made
0
Output length
0 chars
Rule errors
0
All rules valid

Output is generated locally as you type. Length: 0 characters · diff vs. input: 0.

Sources: replacement follows the ECMA-262 String.prototype.replace spec (special tokens $& $1$9 $` $' in regex mode). Whole-word lookarounds use Unicode property escapes (TR-18) so Sinhala, Tamil, and accented Latin word boundaries are honoured. Full citations in the Sources section below.

How it works

The tool wraps a small, predictable set of JavaScript primitives: String.prototype.matchAll for counting, String.prototype.replace for the actual rewrite, and RegExp for compiling the find pattern. Everything is a pure function — no server call, no shared state, no dependency beyond the standard library.

  1. Compile. Your find pattern is either escaped (plain mode — every regex metacharacter is replaced with its literal backslash form) or passed through verbatim (regex mode). The global and unicode flags are always set; case-insensitive, multiline, and dot-all flags are added when their toggles are on.
  2. Whole-word wrap. When the W toggle is enabled, the pattern is sandwiched between two Unicode-aware lookarounds: (?<![\p{L}\p{N}\p{M}_]) before, and (?![\p{L}\p{N}\p{M}_]) after. That treats every Unicode letter, digit, or combining mark as a word character, which is what makes "cat" inside "scat" not match and what keeps "කවිය" inside "කවියා" from matching either.
  3. Count. The tool runs text.matchAll(regex) to iterate every non-overlapping match. Zero-width matches (anchors like ^, $, lookarounds) are advanced past automatically by the engine's AdvanceStringIndex algorithm, so the loop terminates even on patterns like /^/g.
  4. Replace. A fresh compiled regex is passed to text.replace. In regex mode the replacement is passed as a string so $1, $&, $` and friends work per ECMA-262. In plain mode the replacement is passed as a function returning the literal string, which disables the dollar-sign expansion — so a replacement like $10 stays as the two characters "$" and "10".
  5. Cross-check. A second counter is run via replace with a counting callback. The verified badge stays green only when both counters agree on the number of matches — the invariant countByMatchAll(t, p) === countByReplace(t, p) holds for every well-formed input.

Multi-rule mode is a thin loop on top of the single-rule path. Rules are applied left-to-right; each rule's output becomes the next rule's input; per-rule counts and any compile errors are surfaced separately so a typo in rule 3 does not silently mask a working rule 4. The pipeline stops at 50 rules, which is well above any realistic codemod or glossary table.

Escape interpretation in the replacement is opt-in. When enabled, a small switch turns \n into a real newline, \t into a tab, \r into a carriage return, and \\ into a single backslash. Unknown escapes (e.g. \q) are left exactly as the user typed them, so a stray backslash is never silently dropped.

Worked examples

Plain replace, case-sensitive

text="the cat sat on the mat", find="the", replace="THE"

  1. Compile: escape regex specials → /the/gu
  2. matchAll: positions 0 and 15 → count=2
  3. Replace: produces 'THE cat sat on THE mat'
  4. Cross-check: replace-callback also reports 2 → verified

Whole-word with near-misses

text="cat scat cats catalog cat.", find="cat", whole=on

  1. Pattern wrapped: (?<![\p{L}\p{N}\p{M}_])cat(?![\p{L}\p{N}\p{M}_])
  2. scat → preceded by 's' (letter) → fails lookbehind
  3. cats → followed by 's' (letter) → fails lookahead
  4. catalog → followed by 'a' (letter) → fails lookahead
  5. Only positions 0 (start, then space) and 22 (after space, then '.') qualify
  6. Result: count=2

Regex backreference

text="John 25, Mary 30", find=/(\w+) (\d+)/, replace="$2 ($1)"

  1. Compile (regex on): /(\w+) (\d+)/gu
  2. matchAll: two non-overlapping matches → count=2
  3. Replace passes the string verbatim so $1 and $2 expand per ECMA-262
  4. Output: '25 (John), 30 (Mary)'

Multi-rule pipeline (small codemod)

text="AAA BBB", rules=[AAA→X, BBB→Y]

  1. Rule 1: 'AAA BBB' → 'X BBB' (count=1)
  2. Rule 2 reads the rule-1 output: 'X BBB' → 'X Y' (count=1)
  3. Total = 2, perRule = [1, 1]
  4. Each rule's count is shown beside its row in the UI

Frequently asked questions

Sources & references

The replacement semantics and Unicode word-boundary handling on this page were last cross-checked on 2026-05-11. The page is reviewed whenever a relevant TC39 proposal lands (e.g. the v flag set operations) or a Unicode TR update changes the property-escape definitions used for whole-word matching.

Related tools

Rate this tool
Be the first to rate

Comments & feedback

Spotted a bug or want an improvement? Tell us — our team reviews every comment, and good ideas get built. Comments are public and anonymous.

Spotted a regex edge case, an unexpected count, or want a new toggle?

Email me at [email protected] — most fixes ship within 24 hours.