Regex Tester
Test JavaScript regex with live highlighting
Common flags: g global, i case-insensitive, m multiline, s dotAll, u unicode.
Match details
What is a regex tester?
A regular expression is a compact, declarative way to describe a pattern in text — find every email address in a document, validate that a phone number matches the right format, replace every occurrence of a date in DD/MM/YYYY form with YYYY-MM-DD, or split a CSV row at the right commas. Regular expressions are supported by every major programming language and most text editors, but writing them is error-prone: a single misplaced quantifier can match too much, too little, or fail to compile entirely. A regex tester shows you exactly what your pattern matches in a given test string, so you can iterate quickly without bouncing back and forth to the language's REPL.
This tester uses the JavaScript / ECMAScript regex engine — the same one running inside your browser — and supports the full ECMAScript 2025 feature set: capture groups (numbered and named), lookaround (lookbehind included), Unicode property escapes (\p{Letter}), and all six standard flags. As you type, every match in the test string is highlighted, and capture groups are listed below for each match with their captured text and the index where each one starts. Pattern errors are reported inline so you can fix them as you go. The pattern, flags, and test string are all evaluated in your browser; nothing is sent to a server.
Most regex syntax is portable: a pattern that works in JavaScript will usually work in PCRE (PHP, Python, Ruby), .NET, Go, and Rust with at most cosmetic changes. The differences are in the corners — possessive quantifiers (*+, ++) exist in PCRE but not JavaScript; conditionals ((?(1)yes|no)) are PCRE-only; some Unicode escapes have slightly different names. The portability sections below highlight the differences worth knowing.
Regex syntax in detail
The regex grammar is small but expressive. Below is a tour of each construct with a working example you can paste into the tester to see how it behaves.
Anchors
^start end$ \bword\b
^ matches the start of the input (or the start of any line if the m flag is set), $ matches the end. \b is a word boundary — the gap between a word character and a non-word character. Anchors are zero-width: they assert a position but do not consume any characters.
Character classes
\d \w \s [a-z] [^0-9]
\d matches a digit (0–9 by default; any Unicode digit with the u flag), \w a word character ([A-Za-z0-9_]), \s any whitespace. Custom classes use square brackets — [a-z] for a range, [^0-9] to negate the class. . matches any character except newline (any character including newline with the s flag).
Quantifiers
a* a+ a? a{3} a{2,5}
* matches zero or more, + one or more, ? zero or one. {n} exactly n, {n,m} between n and m, {n,} n or more. All quantifiers are greedy by default — they match as much as possible while still allowing the rest of the pattern to match. Suffix any of them with ? to make them lazy: .*? matches as little as possible.
Alternation
cat|dog|fish
| matches either side. The engine tries the alternatives left-to-right and takes the first one that succeeds — so int|integer against "integer" will match the leading int and stop. Reorder to put longer alternatives first when this matters: integer|int.
Capture groups
(\d{4})-(\d{2})-(\d{2})
Parentheses create a numbered capture group, accessible as $1, $2 in replacements. Use (?:...) for a non-capturing group when you only need the grouping. Named groups use (?<year>\d{4}) and back-reference as \k<year>. Numbered backreferences use \1, \2 inside the pattern.
Lookaround
foo(?=bar) foo(?!bar)
Lookahead and lookbehind are zero-width assertions that match a position based on what follows or precedes, without consuming characters. foo(?=bar) matches foo only when followed by bar; foo(?!bar) only when not followed by bar; (?<=foo)bar matches bar only when preceded by foo. JavaScript supports lookbehind since ES2018; some older PCRE versions only allow fixed-length lookbehind.
Unicode property escapes
\p{Letter} \p{Script=Greek}
With the u flag, \p{...} matches any character with a given Unicode property: \p{Letter} for any letter in any script, \p{Script=Cyrillic} for a specific script, \p{Number} for any kind of digit. \P{...} negates. Useful for patterns that need to work across natural languages.
Flags
/pattern/gimsuy
The trailing letters of a regex literal — set them in the flags box of this tester. g finds all matches (without it, only the first); i case-insensitive; m makes ^ and $ match line boundaries; s makes . match newlines too; u enables Unicode mode (required for \p{}); y sticky mode (anchors at lastIndex).
Common patterns and what they match
Most regex problems are variants of a small set of common patterns. The table below collects the most useful ones with a working example. Paste the pattern into the tester to see it match the example, then adapt it to your input.
| Pattern | Matches | Example match |
|---|---|---|
\d{4}-\d{2}-\d{2} |
ISO 8601 date | 2026-05-07 |
\b[\w.+-]+@[\w.-]+\.\w+\b |
simple email | jane.doe@example.com |
https?:\/\/\S+ |
http(s) URL | https://example.com/page |
#[0-9a-fA-F]{6}\b |
6-digit hex color | #ff8800 |
\b[A-Z]{2,}\b |
all-caps acronym | NASA |
^\s*$ |
empty / blank line | " " |
\b\w+\b |
a word | hello |
\b(\w+)\s+\1\b |
duplicate word | the the |
\(\d{3}\)\s?\d{3}-\d{4} |
US phone (123) 456-7890 | (415) 555-1212 |
v\d+\.\d+\.\d+ |
semver-ish version | v1.2.3 |
^[a-z][a-z0-9-]*$ |
kebab-case slug | my-blog-post |
<[^>]+> |
HTML/XML tag | <p class="x"> |
[\u4e00-\u9fff]+ |
Han/CJK ideographs | 中文 |
\p{Emoji} (with u) |
a single emoji | 🎉 |
How matching works under the hood
JavaScript's regex engine is a backtracking NFA — it tries to match the pattern at each position in the input, and when a branch fails, it backs up and tries another. Greedy quantifiers like .* first try to consume as much as possible, then give back characters one at a time when the rest of the pattern fails to match. This is what makes regex expressive — it can handle nested alternation and lookaround — but it is also what makes some patterns catastrophically slow. Catastrophic backtracking happens when a pattern like (a+)+b on input aaaaaaaaaaaaaa tries an exponential number of ways to split the as before failing. If your pattern has nested quantifiers and your input length is unbounded, sanity-check it on adversarial input. The v flag (ECMAScript 2024) introduces set notation and other refinements that make some patterns easier to write safely; this tester accepts the v flag where the browser supports it.
Frequently asked questions
Which regex flavor does this tester use?
new RegExp(pattern, flags) and matched against your test string in the browser. Most syntax is portable to PCRE (PHP, Python re, Ruby), .NET, Go, and Rust — but advanced features like possessive quantifiers, conditionals, and recursion are PCRE-only and are not supported here.Why do I only get one match?
g (global) flag. Without it, the engine returns only the first match. With g set, this tester iterates over every match in the test string and highlights all of them. Combine with i for case-insensitive matching: gi.How do I make <code class="bg-gray-100 px-1 rounded text-xs">.</code> match newlines?
s (dotAll) flag. By default, . matches any character except a line terminator (\n, \r, \u2028, \u2029). With s, it matches any character including newlines.What's the difference between greedy and lazy quantifiers?
*, +, ?, {n,m}) match as much as possible while still allowing the rest of the pattern to succeed; lazy ones (suffix any quantifier with ?) match as little as possible. Classic example: <.*> on <a>text</a> matches the whole string; <.*?> matches just <a>.Can I use lookbehind?
(?<=...) (positive) and (?<!...) (negative) lookbehind since ES2018, and they have been broadly available in all modern browsers since 2020. Lookbehind in JavaScript can have variable length (older PCRE versions only allow fixed-length lookbehind, which is the most common cross-engine portability gotcha).How do I match a literal special character?
. ^ $ * + ? ( ) [ ] { } | \ /. To match a literal dot, write \.; to match a literal backslash, write \\. Inside a character class, only ^ ] \ - are special and need escaping (and ^ only if at the start, - only if not at the start or end).Why is my regex catastrophically slow?
(a+)+ or (\w*)*. On input that almost matches, the backtracking engine tries an exponential number of ways to split the input before failing. Fix it by making one of the quantifiers more specific — for example, (a+)+ is equivalent to a+, and the latter is linear. As a rule of thumb, never quantify a group whose body is itself unbounded.