Regular expressions (regex or regexp) are one of the most powerful tools in a developer's toolkit โ and one of the most misunderstood. A well-written regex can replace hundreds of lines of string-parsing code in a single pattern. This guide covers the essential building blocks, explains the most common patterns with real examples, and shows you when to use regex and when to reach for something else.
What Is a Regular Expression?
A regular expression is a sequence of characters that defines a search pattern. It is a mini-language for describing strings โ you write a pattern, and the regex engine tests whether a given string matches that pattern, where the match occurs, or what substrings it captures.
Regex is supported in virtually every programming language: JavaScript (RegExp), Python (re module), Java (java.util.regex), Go (regexp), Ruby, PHP, Perl, and many more. Most text editors (VS Code, Sublime Text, IntelliJ) also support regex in their find-and-replace interfaces.
Core Building Blocks
Literal Characters
The simplest regex is just a literal string. The pattern hello matches the exact substring "hello" anywhere in the input. Most characters match themselves literally, with the exception of the special metacharacters: . * + ? ^ $ [ ] | ( ) \. To match one of these literally, escape it with a backslash: \. matches a literal period, \* matches a literal asterisk.
Character Classes
Square brackets define a character class โ a set of characters, any one of which can match at that position:
[abc]โ matches "a", "b", or "c"[a-z]โ matches any lowercase letter[A-Z]โ matches any uppercase letter[0-9]โ matches any digit[^abc]โ matches any character that is NOT "a", "b", or "c" (negated class)[a-zA-Z0-9]โ matches any alphanumeric character
Shorthand Classes
\dโ any digit (equivalent to[0-9])\Dโ any non-digit\wโ any word character: letters, digits, underscore ([a-zA-Z0-9_])\Wโ any non-word character\sโ any whitespace: space, tab, newline, carriage return\Sโ any non-whitespace character.โ any character except newline (use[\s\S]to include newlines)
Quantifiers
Quantifiers specify how many times the preceding element must match:
*โ zero or more times+โ one or more times?โ zero or one time (makes the element optional){n}โ exactly n times{n,}โ n or more times{n,m}โ between n and m times (inclusive)
By default, quantifiers are greedy โ they match as many characters as possible. Adding ? after a quantifier makes it lazy โ it matches as few characters as possible: .*? instead of .*.
Anchors
^โ matches the start of the string (or start of a line in multiline mode)$โ matches the end of the string (or end of a line in multiline mode)\bโ word boundary: the position between a word character and a non-word character\Bโ non-word boundary
Practical Regex Patterns
Email Validation
A production-grade email regex is surprisingly complex, but this pattern covers 99% of real-world email addresses:
/^[^\s@]+@[^\s@]+\.[^\s@]+$/Breakdown: start of string, one or more characters that are not whitespace or @, a literal @, more non-whitespace/@ characters, a literal dot, more non-whitespace/@ characters, end of string. For strict RFC 5322 compliance, use a dedicated email validation library rather than regex.
URL Matching
/https?:\/\/[^\s/$.?#].[^\s]*/Matches URLs starting with http:// or https://. The s? makes the "s" optional.
IP Address Validation
/^(\d3\.)3\d3$/Matches the format of an IPv4 address. Note this also matches "999.999.999.999" โ for valid range checking (0-255), you need a more complex pattern or numeric validation in code.
Remove Non-Alphanumeric Characters
str.replace(/[^a-zA-Z0-9]/g, '')The global flag g replaces all matches, not just the first. This is useful for sanitizing user input before storing it.
Extract All Numbers from a String
str.match(/\d+/g)Returns an array of all digit sequences found in the string. For example, "Order 123 contains 5 items" returns ["123", "5"].
Validate a Slug
/^[a-z0-9]+(?:-[a-z0-9]+)*$/Matches lowercase alphanumeric slugs with hyphens between words. Rejects slugs that start or end with a hyphen or contain consecutive hyphens.
Flags / Modifiers
g(global) โ find all matches, not just the firsti(case-insensitive) โ treat uppercase and lowercase as equalm(multiline) โ make^and$match start/end of each line, not just the whole strings(dotAll) โ make.match newlines too
Capture Groups and Backreferences
Parentheses () create a capture group. The matched content is stored and can be referenced later. This is invaluable for extract-and-reformat operations:
// Reformat date from YYYY-MM-DD to DD/MM/YYYY
"2025-12-31".replace(/(\d4)-(\d2)-(\d2)/, '$3/$2/$1')
// Returns: "31/12/2025"Named capture groups (supported in modern JavaScript, Python, and .NET) make patterns self-documenting:
/(?P<year>\d4)-(?P<month>\d2)-(?P<day>\d2)/When NOT to Use Regex
- Parsing HTML or XML: Use a proper DOM parser. Regex cannot handle the recursive, tag-nesting structure of HTML reliably.
- Parsing JSON: Use JSON.parse(). Regex on JSON strings breaks on edge cases like escaped quotes and nested structures.
- Extremely complex validation: For email validation with full RFC 5322 compliance, credit card validation, or IBAN validation, use a dedicated library. The regex would be hundreds of characters long and nearly impossible to maintain.
- Performance-critical paths with catastrophic backtracking risk: Certain regex patterns (particularly those with nested quantifiers) can exhibit exponential backtracking on pathological inputs, causing a "ReDoS" (Regular Expression Denial of Service) vulnerability.
Testing Your Patterns
The Find & Replace tool on this site supports regex mode โ toggle the regex option and test your patterns against real text directly in your browser without writing any code. This is the fastest way to verify a pattern before committing it to your codebase.