Regular Expressions for Beginners: A Practical Crash Course
Learn regex from zero with plain-English explanations and real patterns you can copy — emails, dates, phone numbers, and the gotchas that trip everyone up.
Regular expressions look like line noise — ^\d{3}-\d{4}$ — but they're built from a small set of rules you can learn in twenty minutes. This crash course covers the 20% of regex that handles 90% of real tasks. Test every example as you go in our Regex Tester.
The core idea
A regex is a pattern that either matches parts of a text or doesn't. Most characters match themselves: the pattern cat matches "cat" inside "concatenate". The power comes from special characters that match categories of things.
The characters that match categories
.— any single character ("c.t" matches cat, cot, c9t)\d— any digit 0–9\w— any "word" character: letter, digit, or underscore\s— any whitespace (space, tab, newline)- Capitalized versions negate:
\D= not a digit,\W= not a word char
Quantifiers: how many times
*— zero or more+— one or more?— zero or one (i.e. optional){3}— exactly 3;{2,5}— between 2 and 5
So \d{3}-\d{4} means: three digits, a hyphen, four digits — a US phone number ending like "555-0123".
Anchors: where in the string
^— start of the string$— end of the string
Without anchors, \d+ finds digits anywhere. With them, ^\d+$ requires the whole string to be digits — the difference between "contains a number" and "is a number." Forgetting anchors in validation is the #1 beginner bug.
Character classes and groups
[abc]— any one of a, b, or c;[a-z]— any lowercase letter;[^0-9]— anything except a digit(cat|dog)— "cat" or "dog", and parentheses also capture what matched for later use
Five patterns you can copy today
A reasonable email check:
^[\w.+-]+@[\w-]+\.[\w.]+$
(Perfect email validation via regex is famously impossible — this catches typos, which is all a form needs.)
A date like 2026-07-15:
^\d{4}-\d{2}-\d{2}$
A US ZIP code (with optional +4):
^\d{5}(-\d{4})?$
Extract all numbers from text:
\d+(\.\d+)?
A hex color code:
^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$
The gotchas that bite everyone
Greedy matching. Quantifiers grab as much as possible. On <b>one</b> and <b>two</b>, the pattern <b>.*</b> matches the entire string — from the first <b> to the last </b>. Add ? to make it lazy: <b>.*?</b> matches each tag pair separately.
Escaping. These characters have special meanings: . + * ? ( ) [ ] { } ^ $ | \. To match one literally, escape it with a backslash: to match "3.14" exactly, write 3\.14 — otherwise the dot matches any character and "3X14" passes too.
Flags. In JavaScript, g finds all matches instead of just the first, i ignores case, and m makes ^ and $ work per-line. Most "why does it only find one match?" questions are a missing g.
How to actually learn it
Don't memorize — build. Open the Regex Tester, paste some real text (a log file, a CSV row, an email), and try to match pieces of it, starting simple and adding one token at a time. The live highlighting shows exactly what each change does. Twenty minutes of that beats any cheat sheet — though we keep one on the tester page anyway.