Regular Expressions Explained with Real Examples
Stop being scared of regex. A practical guide with real patterns you'll actually use, with a tester you can paste them into.
Regular expressions have a reputation for being unreadable. The reputation is partly deserved production regex can look like keyboard-cat output. But for everyday tasks (validation, search-and-replace, log parsing), the patterns are short, learnable, and powerful.
This guide covers the patterns you'll actually use, with real examples you can paste into a regex tester to see them working.
What Is a Regex?
A regex is a search pattern. You give it a string, it tells you which parts match. That's it.
The complexity comes from the special characters that let you describe sophisticated patterns: "any digit", "any letter", "exactly 3 of these", "this OR that".
The Most Common Special Characters
| Character | Means |
|---|---|
. | Any character (except newline by default) |
\d | Any digit (0-9) |
\w | Any word character (letter, digit, underscore) |
\s | Any whitespace character |
* | Zero or more of the previous |
+ | One or more of the previous |
? | Zero or one of the previous |
{n} | Exactly n of the previous |
{n,m} | Between n and m of the previous |
[abc] | Any of a, b, or c |
[^abc] | Any character except a, b, c |
^ | Start of line |
$ | End of line |
() | Capture group |
| | OR |
That's about 90% of regex you'll ever read. The rest is built on top.
Real Pattern 1: Validate an Email (Roughly)
^\w+@\w+\.\w+$
Breakdown:
^start of string\w+one or more word characters (the local part)@literal @\w+one or more word characters (the domain)\.literal dot (escaped, because.alone means any character)\w+one or more word characters (the TLD)$end of string
Try it in the regex tester with john@example.com and not-an-email.
This pattern is good enough for most cases. The full RFC 5322 email regex is famously horrifying for production, just check that the string contains @ and a . after it.
Real Pattern 2: Extract All URLs from Text
https?://[\w.-]+(?:/[\w./?=&%#-]*)?
Breakdown:
https?literal "http" with optional "s" (the?makes the previous character optional)://literal://[\w.-]+one or more word characters, dots, or dashes (the domain)(?:...)?optional non-capturing group (the path)
Paste this into the regex tester with a paragraph that contains URLs and watch them all highlight.
Real Pattern 3: Extract Dates in YYYY-MM-DD Format
\d{4}-\d{2}-\d{2}
That's it. Three groups of digits separated by hyphens.
For more strict matching (months 01-12, days 01-31):
(?:19|20)\d{2}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])
This is a real example of how regex gets ugly fast. For most use cases, the simple version is fine feed the matched dates to a date parser to verify they're real dates.
Real Pattern 4: Find Phone Numbers
\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}
Matches all of these:
(555) 123-4567555-123-4567555.123.45675551234567
Breakdown:
\(?optional opening paren\d{3}three digits\)?optional closing paren[-.\s]?optional separator (hyphen, dot, or space)- repeated for the next groups
Real Pattern 5: Match Hex Color Codes
#[0-9a-fA-F]{3,6}
Matches #fff, #FFF, #1a2b3c, #FFFFFF.
For strict 3 or 6 hex digits only:
#(?:[0-9a-fA-F]{3}){1,2}
Flags You'll Use
Regex flags change how the pattern matches:
| Flag | Effect |
|---|---|
g | Global find all matches, not just the first |
i | Case-insensitive |
m | Multi-line ^ and $ match line boundaries, not just start/end of string |
s | Dotall . also matches newlines |
u | Unicode proper handling of multi-byte characters |
In JavaScript: /pattern/gi. In the regex tester, toggle the flags as buttons.
Capture Groups
Parentheses around a part of the pattern create a capture group a labelled chunk you can extract later:
(\w+)@(\w+\.\w+)
Match against alice@example.com:
- Group 1:
alice - Group 2:
example.com
Capture groups are how you extract structured data from a string. The regex tester shows capture groups for the first match so you can verify your groups before using them in code.
Common Mistakes
Forgetting to escape special characters
example.com matches "exampleXcom" because . means any character. Use example\.com for a literal dot.
Greedy vs lazy matching
<.+> against <a>hello<b> matches <a>hello<b> (greedy as much as possible). Use <.+?> for lazy (as little as possible) matches <a> then <b>.
Forgetting the global flag
/foo/.exec("foofoo") returns the first match only. Add g: /foo/g.exec() for all matches.
Anchoring incorrectly
^abc$ matches only the entire string. ^abc matches strings starting with abc. abc$ matches strings ending with abc. abc matches strings containing abc anywhere.
When to Use Regex (and When Not To)
Use regex for:
- Validation (rough format checks)
- Extracting structured data from unstructured text
- Search-and-replace in text editors
- Simple parsing tasks
Don't use regex for:
- Parsing HTML or XML use a proper parser
- Strict email/URL validation use a library
- Complex grammars use a parser generator
- Anything where a typo in the pattern silently changes behavior
Practice Workflow
The fastest way to learn regex is to iterate fast. Open the regex tester and:
- Paste your test string
- Type a pattern
- See immediately which parts match
- Tweak the pattern, watch the matches change
- Repeat until it does what you want
That feedback loop is the difference between "regex is impossible" and "regex is fast".
The regex tester is your sandbox. Bookmark it and use it any time you need to write a non-trivial pattern. Most regex bugs disappear when you can see the matches as you type.