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.