Regular Expressions Quick Reference
A regular expression matches text by pattern: \d{3}-\d{4} finds 555-1234, and the g flag finds every match instead of only the first. Type a pattern and some test text above to see matches highlighted live, with capture groups and positions. The tester uses your browser's JavaScript RegExp engine, runs locally, and stops runaway patterns after 1.5 seconds.
Regular expressions (regex) are patterns for matching text. The syntax below applies to JavaScript RegExp (used by this tester) and is largely compatible with Python, Java, and most modern languages.
Character Classes
Quantifiers
Anchors & Boundaries
Groups & Lookaround
JavaScript Regex Flags Explained
| Flag | Name | Effect | Example |
|---|---|---|---|
| g | global | Find all matches, not just the first | /a/g on "banana": 3 matches |
| i | ignoreCase | Letters match either case | /cat/i matches "CAT" |
| m | multiline | ^ and $ match at every line start and end | /^\d+/gm finds a number at the start of each line |
| s | dotAll | . also matches line breaks | /a.b/s matches "a\nb" |
| u | unicode | Works in code points; enables \u{...} and \p{...} | /^.$/u matches one emoji; without u it does not |
| y | sticky | Each match must start exactly where the last one ended | /\d/gy on "12a3": 2 matches (1, 2) |
Without g the tester shows only the first match, exactly like str.match(/x/) or re.exec(str). The y flag is used by tokenizers that must not skip characters; in the example, "3" is not matched because "a" breaks the chain.
Regex Token Cheat Sheet
| Token | Matches | Example |
|---|---|---|
\d \w \s | Digit, word character [A-Za-z0-9_], whitespace | \w+ on "id_42!" gives "id_42" |
[abc] [^abc] [a-z] | One of, none of, a range | [aeiou] finds vowels |
* + ? {n,m} | 0 or more, 1 or more, optional, n to m times | colou?r matches color and colour |
*? +? | Lazy versions: as few as possible | <.+?> matches one tag |
^ $ \b | Start, end, word boundary | \bcat\b skips "concat" |
( ) (?: ) (?<name> ) | Capture, group only, named capture | (?<year>\d{4}) |
a|b | Either side | cat|dog |
(?= ) (?! ) (?<= ) (?<! ) | Lookahead and lookbehind, positive and negative | \d+(?=%) takes 15 from "15%" |
\1 \k<name> | Backreference to a group | (\w)\1 finds "ll" in "hello" |
\p{L} (needs u) | Any Unicode letter | \p{L}+ matches "Zoë" |
Catastrophic Backtracking and Zero-Length Matches
JavaScript's regex engine backtracks: when a match fails, it tries every other way the pattern could have split the text. With nested quantifiers such as (a+)+$, (\w+\s?)*$ or overlapping alternatives like (a|aa)*$, the number of ways roughly doubles with each extra character. In a Node.js test, (a+)+$ against 24 a's followed by "!" took about a quarter of a second, and every two more a's made it about four times slower, so 30 a's already take many seconds. That is why the tester runs matching in a background worker and stops it after 1.5 seconds.
- Remove the nesting:
(a+)+matches the same strings asa+. - Make the parts exclusive:
(\w+\s)*\w+instead of(\w+\s?)*, so each character can be matched only one way. - Anchor and limit: use ^, $ and bounded counts like
{1,64}when validating input on a server, where a slow pattern can be a denial of service risk.
Patterns that can match an empty string, such as a*, \b or (?=x), produce zero-length matches. With the g flag the engine then moves ahead one character (one code point with u) and tries again, so a* on "baa" gives 3 matches: "" at 0, "aa" at 1 and "" at 3. The tester counts these separately in the stats bar.
Common Patterns Ready to Copy
| Purpose | Pattern | Notes |
|---|---|---|
| US ZIP code | ^\d{5}(-\d{4})?$ | 12345 or 12345-6789 |
| US phone | ^\(?\d{3}\)?[ .-]?\d{3}[ .-]?\d{4}$ | Format check only, not a real number check |
| ISO date | ^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$ | Still accepts 2026-02-31; check the date in code |
| Hex color | ^#([0-9a-f]{3}|[0-9a-f]{6})$ with i | #fff or #00a67e |
| Whole word | \bword\b | Word boundaries use ASCII \w, even with u |
| Trim spaces | ^\s+|\s+$ with g | Replace with an empty string |
Regex is a poor fit for nested formats. To check JSON, use the JSON formatter; to compare two texts, the diff checker.
Frequently Asked Questions
lastIndex, with no searching ahead. /\d/gy on "12a3" finds 1 and 2, then stops at "a", while /\d/g also finds 3. Sticky matching is used in lexers and parsers that consume input piece by piece.(a+)+ or (\w+\s?)*, lets the engine split the text in exponentially many ways when the overall match fails. This tester stops the search after 1.5 seconds. Rewrite the pattern so each character can be matched only one way, for example a+ instead of (a+)+.