πŸ”Ž Utilities

Regex Tester & Explainer

Test regular expressions with live match highlighting and capture group display. Get a plain-English breakdown of what each part of your pattern does β€” great for learning and debugging.

πŸ” Pattern
/ / gi
Flags:
Quick patterns:
Email URL IPv4 Date Name Hex color
πŸ“ Test String
πŸ“‹ Regex Quick Reference
Characters
\d Digit (0–9)
\w Word char (a-z, A-Z, 0-9, _)
\s Whitespace
. Any char except newline
[abc] Character class
[^abc] Negated class
Quantifiers
* 0 or more
+ 1 or more
? 0 or 1 (optional)
{n,m} Between n and m
*? Lazy (minimal match)
Anchors
^ Start of string/line
$ End of string/line
\b Word boundary
Groups
(abc) Capture group
(?:abc) Non-capture group
(?<name>) Named group
a|b Alternation (a or b)
πŸ“– How to Use This Tool
β–Ό
1
Enter a pattern in the regex field
2
Paste test text β€” matches highlight live
3
View capture groups and values
4
Use the cheatsheet for syntax help
πŸ“ Examples
Emails
Input: [a-z]+@[a-z]+\.[a-z]+
Output: Highlights all emails in text

ReDoS: When Testing a Pattern Here Can Save You From an Outage Later

This tester runs entirely in your browser, so it's a safe place to discover a dangerous pattern before it ever reaches a server. Certain regex shapes β€” nested quantifiers over overlapping alternation, like (a+)+b or ([a-zA-Z]+)* β€” can cause catastrophic backtracking, where a specially crafted input makes the matching engine's runtime explode exponentially with input length. If a pattern you're testing here suddenly makes the browser tab freeze on an input that's only a few characters longer than the last one you tried, that's not a coincidence β€” it's the signature of exponential backtracking, and it means the same pattern would pin a CPU core at 100% for seconds or minutes if it processed attacker-controlled input on a production server. This is a real, named vulnerability class β€” ReDoS, Regular Expression Denial of Service β€” and it has caused genuine outages when a single malicious or malformed input hit a vulnerable validation regex on a public-facing endpoint.

Testing here is a legitimate way to screen for this before deployment: paste your pattern, then deliberately try a long, repetitive, almost-but-not-quite-matching input (a long run of the character your quantifier repeats, followed by a character that breaks the match). If match time visibly degrades as you lengthen that input, rewrite the pattern to avoid the nested-quantifier shape β€” usually by making the inner group possessive-equivalent with a more specific character class, or restructuring the alternation so the branches don't overlap β€” before it ever reaches a form validator or an API gateway rule.

The Alert Rule That Quietly Stopped Firing

An illustrative, generic scenario: a platform team writes a log-based alert rule to catch a specific error signature in application logs, using a regex built and confirmed against a handful of sample log lines pulled from a recent incident. The pattern matches those samples perfectly and the rule ships. Weeks later, the same underlying error starts occurring again, but a minor logging library upgrade changed the timestamp format from a fixed-width field to a variable-width one β€” and the alert rule's regex, which had accidentally hardcoded an assumption about field width via a fixed-count quantifier, silently stops matching. Nobody notices for days, because "the alert didn't fire" produces no signal at all; the failure mode of an untested regex is invisible until someone happens to search the raw logs and finds the errors were there all along. The lesson generalizes: any regex feeding an alert, dashboard, or log parser should be tested here against multiple real samples spanning normal variation β€” not just the one log line that prompted writing it β€” and revisited whenever an upstream logging format changes.

What This Tool Actually Gets Reached For

What Happens Behind the Highlighted Matches

The tool builds a JavaScript RegExp object from your pattern and selected flags with new RegExp(pattern, flags), then repeatedly calls RegExp.prototype.exec() in a loop to walk through every match in the test string, recording each match's start index, matched text, and any capture group values along the way. The live highlighting simply wraps each matched span in the test string with a styled element based on those indices. The pattern explainer works independently: it tokenizes the raw pattern string into its constituent pieces β€” character classes, quantifiers, anchors, groups β€” and maps each one to a plain-English, color-coded label, all computed client-side as you type with no network round-trip involved at any point.

Frequently Asked Questions

What regex flavour does this tool use?

This tool uses JavaScript's built-in RegExp engine, which implements the ECMAScript regular expression specification. It supports standard character classes (\d, \w, \s), quantifiers (*, +, ?, {n,m}), anchors (^, $, \b), capture groups, non-capturing groups, named groups ((?<name>...)), and lookaheads ((?=...), (?!...)). Lookbehind assertions ((?<=...), (?<!...)) are supported in all modern browsers (Chrome 62+, Firefox 78+, Safari 16.4+). Note that some regex features from other languages β€” like PCRE's conditional patterns or atomic groups β€” are not available in the JavaScript regex engine.

How do I test regex flags?

Use the flag toggle buttons above the pattern input to enable or disable individual flags. The g (global) flag finds all matches instead of stopping after the first β€” enable this when you want to see every occurrence highlighted. The i (case-insensitive) flag makes the match ignore case differences between uppercase and lowercase letters. The m (multiline) flag changes the behavior of ^ and $ anchors so they match the start and end of each line rather than the entire string β€” essential for line-by-line log parsing. The s (dotAll) flag makes the . wildcard match newline characters as well, and the u (unicode) flag enables full Unicode character matching and proper handling of multi-byte characters.

What is the difference between a capture group and a non-capturing group?

A capture group, written as (pattern), both groups the pattern for quantifier application and saves the matched substring so it can be referenced later. In JavaScript, captured groups are accessible as match[1], match[2], etc., and in replacement strings as $1, $2, etc. A non-capturing group, written as (?:pattern), groups the pattern without saving the match β€” it is semantically equivalent but more efficient when you only need the grouping behavior (for alternation like (?:jpg|png|gif) or to apply a quantifier to multiple tokens) and do not need the captured value. Named capture groups, written as (?<name>pattern), save the match under a named key accessible as match.groups.name, making your regex code more readable and maintainable when multiple groups are present.