Regex Tester
Test and debug regular expressions with real-time match highlighting.
Regex Is Not Magic — But the Error Messages Make It Feel That Way
Regular expressions have a reputation for being write-only code: you write a pattern, it works, and six months later nobody — including the author — can read it. The reputation is earned, but it is also overstated. Most day-to-day regex use involves a small vocabulary of constructs, and understanding them removes the mystery.
What makes regex frustrating without a tester is that mistakes are silent. A pattern that matches nothing returns no error — it just fails. A pattern with a subtle flaw matches almost everything, including things it should not. A live tester with real-time highlighting is the only practical way to build and verify patterns iteratively.
The Constructs You Actually Use Most Often
The full regex specification is vast, but 90% of practical use cases involve these patterns:
- Anchors:
^matches the start of a string (or line in multiline mode);$matches the end. Without anchors, a pattern for "a 5-digit number" matches any string that contains 5 digits anywhere within it. - Character classes:
[abc]matches a, b, or c.[a-z]matches any lowercase letter.[^abc]matches anything that is not a, b, or c. - Shorthand classes:
\d(digit, same as[0-9]),\w(word character: letters, digits, underscore),\s(whitespace: space, tab, newline). - Quantifiers:
*(0 or more),+(1 or more),?(0 or 1, making the preceding element optional),{n}(exactly n times),{n,m}(between n and m times). - Alternation:
cat|dogmatches "cat" or "dog". Alternation has the lowest precedence —^cat|dog$means "start-of-string followed by cat" OR "dog followed by end-of-string." Use grouping:^(cat|dog)$. - Groups and capture:
(pattern)groups a subpattern and captures the matched text.(?:pattern)groups without capturing — useful for quantifiers without creating a capture group. - Lookahead and lookbehind:
(?=...)asserts that what follows matches, without consuming characters.(?<=...)asserts what precedes. These allow matching based on context without including the context in the match.
Flags That Change Matching Behaviour
- g (global): Find all matches, not just the first one. Without this flag, most regex engines return only the first match.
- i (case-insensitive):
/hello/imatches "hello", "Hello", "HELLO". Without this flag, matching is case-sensitive. - m (multiline): Makes
^and$match the start and end of each line rather than the entire string. Essential when processing multi-line text. - s (dotAll): Makes the
.metacharacter match newline characters. By default,.matches any character except\n.
Using This Tool
- Enter your pattern in the pattern field (without surrounding slashes).
- Set flags using the flag checkboxes or by typing them in the flag field.
- Paste your test string below — matches are highlighted in real time.
- Capture group contents are shown alongside each match.
// faq
What regex flavour does this tool use, and is it compatible with my language? +
This tool uses JavaScript (ECMAScript 2022) regex, which shares most syntax with PCRE (used in PHP, Python's re module, Ruby, Java). The main incompatibilities are: JavaScript does not support lookbehind of variable length in older engines; Python's re module uses (?P<name>) for named groups while JavaScript uses (?<name>); some advanced PCRE features like atomic groups and possessive quantifiers are not available in JavaScript. For Python, PHP, or Java patterns, test here first and verify edge cases in your target language.
How do I match a literal dot, asterisk, or other metacharacter? +
Escape it with a backslash. A plain dot (.) matches any character except newline. To match a literal dot, write \. Similarly, \*, \+, \?, \(, \), \[, \{, \^, \$, \|, and \\ match their literal characters. When in doubt, escape the character — escaping a non-metacharacter is harmless in most flavours.
Why does my pattern match too much, or match things it should not? +
The two most common causes are missing anchors and greedy quantifiers. Without ^ and $, a pattern like \d{5} matches any string containing 5 consecutive digits, not just strings that are exactly 5 digits. Add anchors: ^\d{5}$. For greedy quantifiers (.*, .+), the engine matches as much as possible, which often overshoots. Switch to lazy quantifiers (.*?, .+?) to match as little as possible, or use a more specific character class instead of .
Can regex validate email addresses reliably? +
Not completely. The full RFC 5321 email specification allows characters and formats that most regex patterns do not handle — quoted strings, IP address literals, internationalized domain names. A practical regex like [a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,} catches obvious non-emails but will accept some invalid addresses and reject some valid ones. The only reliable email validation is to send a confirmation email and verify the user can receive it.