Regex Tester
Build and debug regular expressions live. Type a pattern, toggle the flags, and every match
lights up in your test text with its numbered and named capture groups listed below. Switch on
replace mode to preview $1 substitutions, load a common-pattern preset, and keep the
cheatsheet handy. Uses the browser’s native JavaScript RegExp engine, so it behaves
exactly like your code — and nothing is ever uploaded.
Try a common pattern
Click a preset to load its pattern, flags and a sample string, then tweak it.
How to use the regex tester
- Type your pattern in the expression box — no surrounding slashes needed, just the body of the regex.
- Pick the flags you need. Keep
gon to see every match; addifor case-insensitive matching. - Paste your text into the test box. Matches highlight instantly, alternating colours so adjacent matches are easy to tell apart.
- Read the groups — each match lists its numbered and named capture groups so you can confirm you’re extracting the right pieces.
- Preview a replacement — switch on “Show replace” and use
$1,$<name>or$&to rebuild the text. - Copy the result and drop the pattern straight into your JavaScript, TypeScript or Node.js code.
Regex cheatsheet
| Token | What it matches |
|---|---|
. | Any character except newline (matches newline with the s flag). |
\d \D | A digit 0–9 / any non-digit. |
\w \W | A word character [A-Za-z0-9_] / any non-word character. |
\s \S | Any whitespace (space, tab, newline) / any non-whitespace. |
[abc] [^abc] | Any one of a, b, c / any character except a, b, c. |
[a-z] | A range — any lowercase letter. Combine ranges: [A-Za-z0-9]. |
^ $ | Start / end of the string (or of each line with the m flag). |
\b \B | A word boundary / a position that is not a word boundary. |
* + ? | 0 or more / 1 or more / 0 or 1 of the preceding token. |
{n} {n,} {n,m} | Exactly n / n or more / between n and m repetitions. |
*? +? ?? | Lazy (non-greedy) — match as few characters as possible. |
a|b | Alternation — match a or b. |
( ) | A numbered capture group. |
(?<name> ) | A named capture group, referenced as $<name>. |
(?: ) | A non-capturing group (groups without creating a capture). |
(?= ) (?! ) | Positive / negative lookahead. |
(?<= ) (?<! ) | Positive / negative lookbehind. |
\p{L} \p{N} | Unicode property escapes (letter / number) — needs the u flag. |
Tips for writing reliable regular expressions
- Escape special characters — a literal dot, plus or question mark must be written as
\.,\+,\?. Inside a character class, most metacharacters lose their meaning. - Prefer specific over greedy —
"[^"]*"reads a quoted string more safely than".*", which can swallow several strings on one line. - Anchor when you can — adding
^and$(or\bboundaries) prevents partial matches and helps the engine fail fast. - Use named groups —
(?<id>\d+)is far easier to maintain than counting parentheses for$1. - Watch nested quantifiers — patterns like
(a+)+can cause catastrophic backtracking; flatten them to a single character class. - Test the edge cases — empty input, multiple matches per line, and the longest realistic string. A good regex is the one that fails correctly, not just the one that passes once.
Frequently asked questions
What regex syntax does this tester use?
It uses the browser’s native JavaScript (ECMAScript) regular-expression engine — the exact same RegExp implementation your code runs in Node.js, Deno and every modern browser. That means the patterns you test here behave identically in production JavaScript. JavaScript regex differs in small ways from PCRE (PHP/Perl), Python’s re, Java and .NET — for example JavaScript has no inline (?i) modifiers, no possessive quantifiers, and named groups use the (?<name>…) syntax. If you are writing for another language, double-check those edge cases, but for anything JS/TypeScript this is authoritative.
What do the flags g, i, m, s, u and y mean?
g (global) finds every match instead of stopping at the first. i (ignore case) makes the pattern case-insensitive. m (multiline) makes ^ and $ match the start and end of each line rather than the whole string. s (dotAll) lets . match newline characters too. u (unicode) enables full Unicode handling, including \p{…} property escapes and correct surrogate-pair matching. y (sticky) anchors each match to the position right after the previous one (lastIndex). You can combine any of them — this tester shows all matches when g or y is on, and just the first match otherwise, mirroring how RegExp.prototype.exec actually behaves.
How do capture groups and named groups work?
Parentheses ( ) create a numbered capture group; the text each group matched is shown under every result as Group 1, Group 2 and so on, in the order the opening parentheses appear. Use (?<year>\d{4}) to give a group a name — named groups appear in the results by name and can be referenced in a replacement as $<year>. A non-capturing group (?:…) groups part of the pattern for a quantifier or alternation without creating a numbered capture, which keeps your group numbers clean and is slightly faster.
How do I use the replace feature?
Switch on “Show replace” and type a replacement string. Use $1, $2 … to insert numbered capture groups, $<name> for named groups, $& for the whole match, and $$ for a literal dollar sign. For example, pattern (\w+)\s(\w+) with replacement $2 $1 swaps two words. The replacement respects your flags: without the g flag only the first match is replaced. The output is computed with String.prototype.replace, so it matches your code exactly.
Why is my regex showing “Catastrophic backtracking” or running slowly?
Patterns with nested quantifiers on overlapping text — classically (a+)+, (.*)*, or (\w+\s?)+ against a long non-matching string — can make the engine try an exponential number of paths, freezing the tab. This is called catastrophic backtracking and it is a real denial-of-service risk (ReDoS) in production. Fix it by making quantifiers possessive in spirit: anchor the pattern, replace nested groups with a single character class (e.g. [\w\s]+ instead of (\w+\s?)+), or add boundaries so the engine can fail fast. This tester caps iteration to stay responsive, but a pattern that is slow here will be slow in your app too.
Is my pattern or test text uploaded anywhere?
No. Everything runs locally in your browser using the native RegExp engine — your pattern, flags and test string never leave the page and nothing is sent to a server or stored. You can disconnect from the internet and the tester still works. That makes it safe to paste log lines, sample data or anything sensitive while you build a pattern.