A regular expression is a small program that describes a set of strings. A regex tester is the iteration loop: paste a pattern, paste sample input, watch which substrings match. The tool above runs the pattern in your browser using JavaScript’s built-in regex engine; nothing leaves your machine.
The pieces of a pattern
Every regex is a sequence of three kinds of things:
- Literals.
catmatches the three charactersc,a,tin sequence. - Character classes.
\dis any digit,\wis any word character,\sis whitespace,[a-z]is any lowercase letter,[^0-9]is any non-digit. A class consumes one character of input per use. - Quantifiers.
*means zero or more,+means one or more,?means zero or one,{3}means exactly three,{2,5}means two to five. A quantifier applies to the thing immediately before it.
\b\d{3}-\d{4}\b
That pattern matches a US-style phone fragment like 555-1212 and rejects 5551212 or 55-12121. \b is a word boundary — a zero-width assertion that doesn’t consume input but says “the position here must be the edge of a word.”
Anchors, groups, alternation
^matches start of string (or start of line with themflag).$matches end. These are positions, not characters.(...)is a capturing group. Matched text is recoverable as group 1, 2, 3 by position.(?:...)is a non-capturing group — same grouping, no capture.(?<name>...)is a named group; recoverable bynameinstead of by index.|is alternation:cat|dogmatches either word.\1,\2(or\k<name>) are backreferences — match the same text a previous group captured.
Flags change the engine’s behavior
| Flag | Effect |
|---|---|
i | Case-insensitive |
g | Global — find all matches, not just the first |
m | Multiline — ^ and $ match line boundaries inside the input, not just string boundaries |
s | Dotall — . matches newlines (default: . excludes \n) |
u | Unicode — proper handling of code points above U+FFFF |
y | Sticky — match must start at lastIndex |
The tool above defaults to g so you can see every match in the input, not just the first.
Greedy vs lazy
.* is greedy: it matches as much as it can, then backtracks if needed. .*? is lazy: it matches as little as possible, expanding only when forced. The classic case:
Input: <b>bold</b> and <i>italic</i>
Greedy: <.*> → matches "<b>bold</b> and <i>italic</i>" (one giant match)
Lazy: <.*?> → matches "<b>", "</b>", "<i>", "</i>" (four matches)
When extracting tags or quoted strings, lazy quantifiers usually do what you mean. Greedy quantifiers are correct when you want the largest enclosing span.
What regex isn’t good at
- Parsing HTML or XML. Nested, recursive structures defeat regular grammars. Use a parser.
- Validating email exhaustively. RFC 5322 email syntax is famously baroque; the practical pattern
^\S+@\S+\.\S+$plus an actual delivery test is what real systems do. - Matching balanced brackets. Standard regex (without recursive extensions) can’t count.
- Anything where the input language has nesting. JSON, code, math expressions — use a real parser.
Engine differences matter
The tool above uses JavaScript’s regex engine, which differs from Perl, PCRE, Python’s re, Go’s regexp, and grep in small but consequential ways:
- JavaScript supports lookbehind (
(?<=...),(?<!...)) only in modern engines (ES2018+). Older targets need workarounds. - Go’s
regexppackage uses RE2, which guarantees linear time but doesn’t support backreferences or lookahead. - Perl/PCRE support recursive patterns and conditionals; JavaScript doesn’t.
- POSIX-style character classes like
[:alpha:]work ingrepbut not in JavaScript regex.
If a pattern that works in Python fails here (or vice versa), engine differences are the first place to look. The regex cheat sheet documents the JavaScript-flavor syntax this tool uses.
Catastrophic backtracking
A pattern like (a+)+$ against an input of aaaaaaaaaaaaaaaaaab can take exponential time — the engine tries every possible split of the a runs across the nested + before giving up. If a regex makes the page hang, suspect nested quantifiers over the same character class. Restructure the pattern to avoid the ambiguity, or switch to an engine like RE2 that refuses these patterns by construction.
For pattern reference and common constructs, see the regex cheat sheet.