Skip to content

Regex Tester

Test and debug JavaScript regular expressions with live highlighting, capture groups, and step-by-step explanation.

Regex tester

Updates as you type
Pattern
Regular expression ? /…/
/
/ g
Flags g
Presets ?
Test input
Test string ?
Output
Highlighted

        
Match list

How regular expressions work

A regular expression is a tiny pattern language for describing text. This tool uses the JavaScript engine (built into your browser), so every pattern you type here behaves exactly like new RegExp(…) in a .js file.

  1. Compile. The engine parses your pattern into an internal state machine. Syntax errors surface here — that is the “Invalid regex” box.
  2. Scan. The engine walks through the test string from left to right, trying the pattern at each position.
  3. Match or backtrack. When a token fails, it backtracks and tries another branch (alternatives |, greedy vs. lazy quantifiers, optional groups).
  4. Collect. With the g flag it keeps going after each match; without g it stops at the first hit.

JavaScript vs. PCRE (PHP / Python)

If you’ve written regex in other languages, a few things differ:

  • Flag letters are similar: g i m s u. JS also has y (sticky) and d (hasIndices). PCRE adds x (extended), which JavaScript does not support.
  • Lookbehinds (?<=…) and (?<!…) work in modern JS engines but are variable-width-only in older ones.
  • Possessive quantifiers a++, a*+ and atomic groups (?>…) do not exist in JavaScript.
  • Recursion (?R) and subroutine calls (?1) are PCRE-only.
  • Unicode property escapes \p{Letter} require the u flag in JS.

Common pitfalls

  • Greedy by default. .* grabs as much as possible. To match the shortest thing, use lazy .*?.
  • Catastrophic backtracking. Nested quantifiers like (a+)+$ can freeze the browser on pathological inputs. Prefer possessive-style patterns that fail fast — e.g. \w+@\w+ over (\w+)+@\w+.
  • Anchors need the right flag. ^ and $ match the start/end of the whole string by default. Add the m flag to make them match per-line.
  • Dot stops at newlines. Use the s flag when you need . to cross line breaks.
  • Escape inside character classes. Inside […] the only metacharacters are ] \ ^ -. Everything else is literal — you do not need to escape . or *.
  • Global + exec() in real code: RegExp.lastIndex is stateful. If you’re iterating matches in JS, either use String.matchAll() or reset lastIndex.

Worked examples

Email (simplified)/(\w+)@(\w+\.\w+)/g

Matches a word-character block, an @, then a word.dot.word. Two capture groups let you extract the local part and the domain. Real-world emails are more complex — the RFC 5322 grammar is far nastier — but this is enough for log scraping and form validation hints.

ISO date/\b(\d{4})-(\d{2})-(\d{2})\b/g

Three fixed-width digit groups separated by dashes, wrapped in word boundaries so it does not match mid-string. For strict validation you’d also constrain months to 0[1-9]|1[0-2].

IPv4/\b(?:\d{1,3}\.){3}\d{1,3}\b/g

A non-capturing group (?:…) repeated three times, plus a final octet. This matches the shape only — 999.999.999.999 passes. For strict validation, each octet becomes 25[0-5]|2[0-4]\d|[01]?\d\d?.

Extract and reformat/(\d{4})-(\d{2})-(\d{2})/ → $3/$2/$1

In the Replace tab, this turns every 2024-07-04 into 04/07/2024. $1, $2, $3 are back-references to the capture groups.

Strip HTML tags/<[^>]+>/g

[^>]+ means “one or more non-> characters”. Faster and safer than a greedy .* because the character class cannot backtrack across tag boundaries. Still not a real HTML parser — use a DOM parser for anything serious.

When not to use regex

  • HTML, XML, JSON. Use a parser. Regex can’t balance nested structures.
  • Email RFC compliance. The full grammar is ~6 KB. Use a dedicated library or a simple "contains @ and a dot after it" check plus a verification email.
  • Dates with calendar rules. Regex can match the shape, not leap years.
  • Natural-language parsing. Almost always the wrong tool — reach for a tokeniser or an LLM.