induwara.lk
induwara.lkDeveloper · Utility

Regex Tester — Test & Debug Regular Expressions

Test a JavaScript regular expression against any text. Live match highlights, capture groups, replacement preview, flag toggles, and a construct-by-construct explainer — every keystroke processed locally in your browser.

By Induwara AshinsanaUpdated May 11, 2026
Test your regexECMA-262 · live
//

Effective regex: /\d+/g

Presets

Runs entirely in your browser. Nothing is uploaded, logged, or stored.256 chars

Matches
25
Replacements
25
Active flags
/g/
Eval time
0.2 ms
Highlighted input
Contact: [email protected], +94 71 234 5678
Office: 0112345678 (open 09:0017:00)
Site: https://induwara.lk launched on 2026-05-11.
Old NIC 901234567V; reference 550e8400-e29b-41d4-a716-446655440000.
Brand colours: #1e3a8a (sapphire) and #f59e0b (saffron).
Match 1[2931)94
Match 2[3234)71
Match 3[3538)234
Match 4[3943)5678
Match 5[5262)0112345678
Match 6[6971)09
Match 7[7274)00
Match 8[7577)17
Match 9[7880)00
Match 10[120124)2026
Match 11[125127)05
Match 12[128130)11
Match 13[140149)901234567
Match 14[162165)550
Match 15[166170)8400
Match 16[172174)29
Match 17[176178)41
Match 18[179180)4
Match 19[182185)716
Match 20[186198)446655440000
Match 21[216217)1
Match 22[218219)3
Match 23[220221)8
Match 24[240242)59
Match 25[243244)0

Sources: every transform follows the ECMA-262 specification — see RegExp, String.prototype.matchAll, and String.prototype.replace. Full citations in the Sources section below.

How it works

The tester wraps three JavaScript primitives: new RegExp(pattern, flags) for compilation, String.prototype.matchAll for iteration, and String.prototype.replace for the rewrite. The whole thing is a pure function — no server call, no shared state, no dependency beyond the standard library.

  1. Compile.Your pattern and the flag toggles are passed to the JavaScript engine's own RegExp constructor. The gflag is added unconditionally so iteration over multiple matches is well defined; any syntax error surfaces under the field with the engine's native diagnostic message rather than a generic "invalid pattern" string.
  2. Match. The tool calls text.matchAll(regex) to walk every non-overlapping match. Zero-width matches (anchors like ^, lookarounds) are advanced past by the engine's AdvanceStringIndex algorithm in ECMA-262 §22.2.7.4, so a pattern like (?=\d) terminates instead of spinning forever.
  3. Extract groups. For each match the tool reads m[1] through m[n] for numbered captures and m.groupsfor named captures. The numbered groups list also surfaces the name (if any) by parsing the source pattern's group order — that gives a clean $1 (year) label even when several named groups share a value.
  4. Replace. A fresh compiled regex is passed to text.replace with the replacement string verbatim, so $1, $&, $`, $', and $<name> expand per ECMA-262 §22.1.3.18. The result is what your code would produce with the same pattern, byte for byte.
  5. Cross-check. A second counter runs through replace with a counting callback. The Verified badge stays green only when both counters agree on the number of matches — the invariant countByMatchAll === countByReplace must hold for every well-formed input.
  6. Explain.The Explain tab tokenises your pattern and names each construct — anchors, character classes, capture groups, quantifiers, escapes. It is a structural walk, not a full parser; tokens it cannot classify fall through as "literal", and the engine itself remains the authoritative source of truth for what compiles.

The flag set is the standard ECMA-262 alphabet: g global, i case-insensitive, m multiline, s dot-all, u Unicode, and y sticky. The Unicode flag enables \p{...} property escapes from Unicode TR-18, so a pattern like \p{L}+ matches a run of letters in any script — Sinhala (සිංහල), Tamil (தமிழ்), Cyrillic, accented Latin, CJK.

Performance: a megabyte of text against a typical pattern resolves in single-digit milliseconds on a mid-range phone. The page caps the input at 1,000,000 characters and the pattern at 10,000 — past those, the input is trimmed and a notice appears. Catastrophic backtracking is the one workload the tool cannot magically fix — if a pattern feels stuck, anchor it or rewrite the alternation; the iteration cap stops it from freezing the page.

Worked examples

Digit runs in a sentence

pattern="\d+", text="abc 123 def 4567", flags="g"

  1. Compile: /\d+/gu
  2. matchAll → ["123" at offset 4, "4567" at offset 12]
  3. count=2, marked verified by the replace-callback counter
  4. Replace with "#" → output="abc # def #"

Named-group date split

pattern="(?<year>\d{4})-(?<month>\d{2})", text="2026-05", flags="gu"

  1. Compile: /(?<year>\d{4})-(?<month>\d{2})/gu
  2. One match: "2026-05" with groups.year="2026", groups.month="05"
  3. Numbered list shows $1 (year)=2026, $2 (month)=05
  4. Replace with "$<month>/$<year>" → output="05/2026"

Unicode property escape (Sinhala syllable + Latin word)

pattern="[\p{L}\p{M}]+", text="කවිය hello", flags="gu"

  1. u flag enables \p{...} property escapes (Unicode TR-18)
  2. Vowel sign "ි" (U+0DD2) is category Mark, so \p{L}+ alone splits the Sinhala word
  3. Including \p{M} bundles the syllable: matches ["කවිය" at [0,4), "hello" at [5,10)]
  4. count=2 — without the u flag the pattern is a syntax error

Zero-width lookahead — must NOT infinite-loop

pattern="(?=\d)", text="a1b2", flags="g"

  1. Compile: /(?=\d)/gu — zero-width assertion
  2. Engine's AdvanceStringIndex moves lastIndex by 1 after each empty hit
  3. Two zero-width matches at offsets 1 and 3 — count=2
  4. Iteration terminates after text.length+1 steps, never spinning

Frequently asked questions

Sources & references

The tool's match and replace semantics were last cross-checked against the JavaScript engine on 2026-05-11. The page is reviewed whenever a relevant TC39 proposal lands — for example the v flag for set operations — or a Unicode TR update changes the property-escape definitions.

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.

Found a regex edge case, a count mismatch, or want a new preset?

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