Regex tester
Test regular expressions with live highlighting, flags and capture groups. Runs in your browser.
Runs 100% in your browserHow to test a regular expression
- Enter a pattern. Type your regex and toggle the flags you need.
- Add test text. Paste the string to match against; matches highlight live.
- Inspect matches. Review the match list and capture groups below.
What a regular expression is
A regular expression is a compact pattern language for finding, validating and extracting text. Instead of writing loops to scan characters, you describe the shape of what you want — "a four-digit year", "an email address", "everything between two quotes" — and the engine finds every place that shape occurs. They power form validation, log parsing, search-and-replace across a codebase, URL routing and countless data-cleaning jobs. They are also famously easy to get subtly wrong, which is exactly why a live tester that highlights matches and breaks out capture groups as you type saves so much trial and error.
The building blocks
Most patterns are assembled from a small vocabulary. Literals match themselves
(cat matches "cat"). Character classes match one of a set:
[a-z] any lowercase letter, \d a digit, \w a word character,
. any character. Quantifiers say how many: * zero-or-more,
+ one-or-more, ? optional, and {2,4} a specific range —
so \d{4} is exactly four digits. Anchors pin position:
^ start, $ end, \b a word boundary. Groups (…) capture a sub-match for reuse, and (?:…) groups without capturing. Combine
them and \b\w+@\w+\.\w+\b reads as "word, @, word, dot, word" — a rough email matcher.
Flags, greedy vs. lazy, and capture groups
The flags beside the pattern change how the whole expression behaves: g finds every match
rather than just the first, i ignores case, m makes ^ and
$ match at line breaks, and s lets . span newlines. Quantifiers
are greedy by default — they grab as much as possible then backtrack — so a pattern like
".*" across a line with two quoted strings will swallow both; adding ? makes it
lazy (".*?") and stops at the first close. Each capture group you add shows
up in the match breakdown below, numbered left to right; naming them with
(?<name>…) makes both the pattern and any replacement far easier to follow.
Common gotchas
Two mistakes account for most regex pain. The first is forgetting to escape
metacharacters: a literal dot is \., a literal ( is \(, and so on
— an unescaped . quietly matches anything. The second is catastrophic
backtracking: nesting quantifiers over overlapping patterns (the textbook case is
(a+)+) can make the engine explore exponentially many paths and appear to hang. Prefer
specific classes over a bare .*, avoid nesting quantifiers, and anchor the pattern where you
can. Because this tester uses your browser's own engine, every behaviour you see here — flags, groups,
edge cases — is exactly what your JavaScript or Node code will do. To work on the text you are matching,
the case converter
and diff checker
are handy companions. Putting a pattern into code? Our guide to
regular expressions in JavaScript
covers the methods, flags, named groups and the stateful /g lastIndex gotcha.
Frequently asked questions
- Yes — "regex" is just shorthand for regular expression. Paste a pattern and a test string and it highlights every match live, with numbered and named capture groups, using your browser's own JavaScript regular-expression engine.
- JavaScript (ECMAScript) regular expressions — the same engine as Node and browsers. Most PCRE patterns work, but some constructs (e.g. recursion, atomic groups, certain lookbehinds in old browsers) differ. If you are writing the regex for JS or Node, what works here works there.
- g (global — find all matches, not just the first), i (ignore case), m (multiline — ^ and $ match line boundaries), s (dotAll — . also matches newlines), u (unicode) and y (sticky). Toggle them next to the pattern.
- Yes — each match lists its numbered and named capture groups, and matches are highlighted in the test string. Named groups (?
\d{4}) appear by name, which makes a complex pattern far easier to read and to use in replacements. - By default quantifiers are greedy: .+ grabs as much as it can, then backtracks. Add a ? to make them lazy: .+? grabs as little as possible. The classic bug is using .* between delimiters and matching far more than intended — switch to a lazy quantifier or a negated class like [^"]+ instead.
- Almost always catastrophic backtracking — nested quantifiers over overlapping patterns, like (a+)+ against a long non-matching string, force the engine to try exponentially many paths. Avoid nesting quantifiers, prefer specific classes over .*, and anchor the pattern where you can.
- No — matching runs entirely in your browser, so you can test patterns against log lines, customer data or anything sensitive without it leaving the tab.