Regular expressions have a reputation for being cryptic, but they're one of the most powerful tools in a developer's toolkit. Once you internalize the core concepts, you'll be able to validate email addresses, parse log files, extract data, and manipulate strings in ways that would take dozens of lines of code otherwise.
Core Building Blocks
Literal Characters
The simplest regex is a literal string. The pattern hello matches the exact text "hello" wherever it appears in the input.
Metacharacters
Certain characters have special meaning in regex. These are metacharacters:
. * + ? ^ $ { } [ ] ( ) | \
To match a literal metacharacter, escape it with a backslash: \. matches a literal dot, \$ matches a dollar sign.
The Dot .
Matches any single character except a newline. c.t matches "cat", "cut", "c4t", "c!t".
Character Classes [...]
Square brackets define a set of characters to match. [aeiou] matches any single vowel. [a-z] matches any lowercase letter. [^aeiou] matches any character that is NOT a vowel (the ^ inside brackets negates the class).
Shorthand Classes
| Shorthand | Equivalent | Matches |
|---|---|---|
| \d | [0-9] | Any digit |
| \D | [^0-9] | Any non-digit |
| \w | [a-zA-Z0-9_] | Word character |
| \W | [^a-zA-Z0-9_] | Non-word character |
| \s | [ \t\n\r] | Whitespace |
| \S | [^ \t\n\r] | Non-whitespace |
Quantifiers
Quantifiers specify how many times a pattern must match:
| Quantifier | Meaning | Example |
|---|---|---|
| * | 0 or more | ab* → "a", "ab", "abb", "abbb" |
| + | 1 or more | ab+ → "ab", "abb" (not "a") |
| ? | 0 or 1 (optional) | colou?r → "color", "colour" |
| {n} | Exactly n times | \d{4} → "2025" |
| {n,m} | Between n and m times | \d{2,4} → "25", "250", "2025" |
Anchors
Anchors match positions, not characters:
- ^ — start of string (or start of line with
mflag) - $ — end of string (or end of line with
mflag) - \b — word boundary (transition between \w and \W)
Use ^\d{5}$ to validate a US ZIP code — exactly 5 digits, nothing else.
Capturing Groups (...)
Parentheses create a capturing group. The text matched inside is captured separately and accessible as a numbered group. This is powerful for extraction:
Pattern: (\d{4})-(\d{2})-(\d{2})
Input: "Date: 2025-07-20"
Group 1: "2025" (year)
Group 2: "07" (month)
Group 3: "20" (day)
The Dev Cosmos Regex Tester shows all captured groups in the match list below each match.
Non-Capturing Groups (?:...)
If you need grouping for alternation or quantifiers but don't need to capture the value, use (?:...). This is slightly faster and keeps group numbering clean.
Flags (Modifiers)
| Flag | Name | Effect |
|---|---|---|
g | Global | Find all matches, not just the first |
i | Case-insensitive | hello matches "Hello", "HELLO" |
m | Multiline | ^ and $ match start/end of each line |
s | DotAll | The . matches newlines too |
u | Unicode | Enables full Unicode matching (emoji, non-ASCII) |
Common Patterns — Copy & Use
// Email address
[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}
// URL (http/https)
https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&\/=]*)
// IPv4 address
\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b
// UUID
[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}
// Hex color
#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})\b
// ISO 8601 date
\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])
// URL slug
^[a-z0-9]+(?:-[a-z0-9]+)*$
Lookaheads and Lookbehinds
These are zero-width assertions — they check for a pattern without consuming characters:
- (?=...) — Positive lookahead: match if followed by pattern. \d+(?= dollars) matches the number in "100 dollars"
- (?!...) — Negative lookahead: match if NOT followed by pattern
- (?<=...) — Positive lookbehind: match if preceded by pattern
- (?<!...) — Negative lookbehind: match if NOT preceded by pattern
Using the Dev Cosmos Regex Tester
- Type your pattern in the /pattern/ input at the top
- Toggle flags using the chips below (g, m, i, s, u)
- Paste your test string in the lower panel
- Matches highlight in real time — amber for all matches, cyan for the selected one
- Click any match in the list to highlight it in the text and see captured groups
- Use the Presets row to load common patterns (email, URL, UUID, etc.) instantly