Regular Expression Basics
A regular expression (regex) is a pattern that describes text. This guide covers the building blocks you will use most often and the pitfalls that cause slow or surprising matches.
Literals and Character Classes
Most characters match themselves: the pattern cat finds the text "cat". Some
characters have special meaning, such as . * + ? ( ) [ ] { } ^ $ | \. To match one of
them literally, escape it with a backslash, for example \. for a full stop.
A character class matches one character from a set. [abc] matches a, b or c;
[a-z] matches a lowercase ASCII letter; [^0-9] matches anything that is
not a digit. Common shorthands are \d (digit), \w (letter, digit or
underscore), \s (whitespace) and their opposites \D, \W
and \S. The dot . matches any character except a line break.
In JavaScript, \w and \d cover ASCII characters only. To match letters
in any language, use a Unicode property such as \p{L} with the u flag.
Quantifiers and Anchors
Quantifiers say how many times the previous item may repeat:
| Syntax | Meaning | Example |
|---|---|---|
* |
0 or more | ab* matches a, ab, abbb |
+ |
1 or more | \d+ matches 7 or 2026 |
? |
0 or 1 | colou?r matches color and colour |
{n,m} |
Between n and m | \d{2,4} matches 2 to 4 digits |
Anchors match a position rather than a character. ^ is the start and $
the end of the input (or of each line with the m flag). \b is a word
boundary, so \bcat\b finds "cat" but not "concatenate". When validating a whole value,
anchor both ends: ^\d{5}$ accepts exactly five digits and nothing else.
Groups and Captures
Parentheses group part of a pattern so a quantifier or alternation applies to it:
(ab)+ repeats "ab", and (jpg|png) matches either word. A normal group
also captures the matched text, which you can reuse in a replacement as $1,
$2 and so on.
Named groups such as (?<year>\d{4}) make patterns easier to read and can be
referenced as $<year>. If you only need grouping, a non-capturing group
(?:...) avoids creating an unused capture. The LeedyBox RegEx Tester lists each match
with its capture groups and previews replacements.
Flags
Flags change how the whole pattern behaves. The common JavaScript flags are:
g(global): find all matches instead of only the first.i(ignore case): treat upper and lower case as equal.m(multiline):^and$match at each line break.s(dotAll):.also matches line breaks.u(unicode): enables Unicode-aware matching and\p{...}classes.
JavaScript also has y (sticky) and d (match indices), which the tester
supports as well.
Greedy vs Lazy, and Catastrophic Backtracking
Quantifiers are greedy by default: they match as much as possible and then give characters back
if the rest of the pattern fails. On the text <b>bold</b>, the pattern
<.+> matches the entire string. Adding ? makes the quantifier lazy,
so <.+?> matches <b> alone. A negated class such as
<[^>]+> is often clearer and faster.
Most regex engines, including JavaScript's, use backtracking. Nested quantifiers like
(a+)+$ or overlapping alternatives can make the engine try a huge number of
combinations when a match fails, which can freeze a page or a server. This is known as
catastrophic backtracking, and with untrusted input it can be used for denial-of-service attacks
(ReDoS). Avoid nesting quantifiers over the same characters, prefer specific classes over
.*, and test patterns with long inputs that do not match.
Regex Flavours Differ
There is no single regex standard. JavaScript, Python, Java, .NET, PCRE (used by PHP), Go and databases each support slightly different syntax. Lookbehind, possessive quantifiers, named group syntax, Unicode classes and replacement syntax vary. Go's RE2 engine, for example, does not support lookaround or backreferences.
The LeedyBox RegEx Tester uses your browser's JavaScript engine. A pattern that works there may need changes in another language, so test it again where it will run.
Frequently Asked Questions
Why does my pattern match only the first occurrence?
Without the g flag, JavaScript stops after the first match. Enable g to find all matches.
Can a regex validate email addresses?
A regex can check that a value looks plausible, but it cannot confirm that an address exists. Sending a confirmation email is the usual way to verify it.
Why does ^ match only once in multi-line text?
By default ^ and $ refer to the whole input. Turn on the m flag to make them match at the start and end of each line.