Skip to content

Regex Tester

Test a regular expression against sample text. Shows capture groups and an optional replacement preview.

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. cat matches the three characters c, a, t in sequence.
  • Character classes. \d is any digit, \w is any word character, \s is 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 the m flag). $ 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 by name instead of by index.
  • | is alternation: cat|dog matches either word.
  • \1, \2 (or \k<name>) are backreferences — match the same text a previous group captured.

Flags change the engine’s behavior

FlagEffect
iCase-insensitive
gGlobal — find all matches, not just the first
mMultiline — ^ and $ match line boundaries inside the input, not just string boundaries
sDotall — . matches newlines (default: . excludes \n)
uUnicode — proper handling of code points above U+FFFF
ySticky — 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 regexp package 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 in grep but 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.