What regular expressions actually are
A regular expression is a pattern that describes a set of strings. Given a regex pattern and an input string, the regex engine finds the parts of the string that match the pattern. This lets you search, validate, extract, and replace text with concise declarative notation rather than writing loops and conditional logic. The same pattern concept — and largely the same syntax — works in JavaScript, Python, Java, Go, Ruby, Rust, and most other languages, making regex one of the most transferable technical skills in software engineering.
Literals and metacharacters
Most characters in a regex match themselves literally. The pattern hellomatches the string "hello". Metacharacters are characters with special meaning that you need to escape with a backslash if you want to match them literally:
. * + ? ^ $ { } [ ] ( ) | \The dot . is the most used metacharacter — it matches any single character except a newline. a.cmatches "abc", "a1c", "a c", but not "ac" (no character in the middle) or "abbc" (two characters).
Character classes
Square brackets define a character class — a set of characters where any one of them will match:
[aeiou] // matches any vowel [a-z] // matches any lowercase letter (range) [A-Za-z] // matches any letter [0-9] // matches any digit [^0-9] // matches any non-digit (^ inside [] means negation)
Shorthand classes save you from typing the full bracket expression:\\d = [0-9],\\w = [a-zA-Z0-9_],\\s = any whitespace. Uppercase versions are negated: \\D, \\W, \\S.
Quantifiers: how many times?
* // 0 or more
+ // 1 or more
? // 0 or 1 (optional)
{3} // exactly 3
{2,5} // 2 to 5
{3,} // 3 or more
// Add ? to make any quantifier lazy (match as few as possible):
*? +? {2,5}?Greedy quantifiers (*, +) match as much as possible. Applied to <.*> against <b>text</b>, greedy matching captures the entire string. The lazy version <.*?> stops at the first > and matches only <b>.
Groups and capturing
// Capturing group — captures the matched text
(\d{4})-(\d{2})-(\d{2}) // captures year, month, day separately
// Named group — reference by name in replacements
(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})
// Non-capturing group — groups without capturing
(?:cat|dog)s // matches "cats" or "dogs", no captureIn JavaScript, access captures from str.match() at indices 1, 2, 3... Named groups are in match.groups.year. In replacement strings, use $1, $2 or $<year> for named groups.
Essential patterns every developer should know
// Email (basic)
/^[\w.+-]+@[\w-]+\.[a-z]{2,}$/i
// URL
/https?:\/\/[^\s]+/
// UUID
/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i
// ISO date (YYYY-MM-DD)
/\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])/
// Hex color
/#(?:[0-9a-fA-F]{3}){1,2}\b/
// Duplicate words
/\b(\w+)\s+\1\b/gPractice with our tool
Regex Tester — test patterns with live highlighting →