What Is a Regular Expression?
A regular expression (regex) is a pattern that describes a set of strings. Regex engines scan text and find (or extract, or replace) substrings that match the pattern. They're built into virtually every programming language and are indispensable for text validation, parsing, and transformation tasks.
In JavaScript: const pattern = /hello/i; matches "hello", "Hello", "HELLO" (case-insensitive with the i flag).
Character Classes
Character classes define a set of characters to match at a single position:
| Pattern | Matches |
|---|---|
[abc] | a, b, or c |
[^abc] | Any character except a, b, c |
[a-z] | Any lowercase letter |
[A-Za-z0-9] | Any alphanumeric character |
. | Any character except newline |
d | Digit (equivalent to [0-9]) |
D | Non-digit |
w | Word character [a-zA-Z0-9_] |
W | Non-word character |
s | Whitespace (space, tab, newline) |
S | Non-whitespace |
Quantifiers
Quantifiers specify how many times a pattern must appear:
| Quantifier | Meaning |
|---|---|
* | 0 or more |
+ | 1 or more |
? | 0 or 1 (optional) |
{n} | Exactly n times |
{n,} | n or more times |
{n,m} | Between n and m times |
By default, quantifiers are greedy — they match as much as possible. Add ? to make them lazy: .*? matches as little as possible.
// Greedy: matches entire string between first and last
const greedy = /<.+>/; // matches <b>hello</b> entirely
// Lazy: matches shortest possible tag
const lazy = /<.+?>/; // matches just <b>
Anchors and Boundaries
| Anchor | Meaning |
|---|---|
^ | Start of string (or line with m flag) |
$ | End of string (or line with m flag) |
| Word boundary |
B | Non-word boundary |
Groups and Captures
Parentheses create groups that capture matched text for later use:
const datePattern = /(d{4})-(d{2})-(d{2})/;
const match = "2025-06-15".match(datePattern);
// match[1] = "2025", match[2] = "06", match[3] = "15"
Named capture groups make code more readable:
const datePattern = /(?<year>d{4})-(?<month>d{2})-(?<day>d{2})/;
const { groups } = "2025-06-15".match(datePattern);
// groups.year = "2025", groups.month = "06", groups.day = "15"
Use (?:...) for non-capturing groups when you need grouping but not extraction:
// Match "color" or "colour" without capturing the "u?"
const pattern = /colou?r/; // or: /col(?:ou?)r/
Lookaheads and Lookbehinds
Lookarounds let you assert context without including it in the match:
| Syntax | Meaning |
|---|---|
(?=...) | Positive lookahead — followed by |
(?!...) | Negative lookahead — NOT followed by |
(?<=...) | Positive lookbehind — preceded by |
(?<!...) | Negative lookbehind — NOT preceded by |
// Match price numbers preceded by $
const pricePattern = /(?<=$)d+(.d{2})?/;
"$29.99".match(pricePattern); // ["29.99"]
// Validate password has at least one digit
const hasDigit = /(?=.*d)/;
hasDigit.test("hello123"); // true
hasDigit.test("helloworld"); // false
Practical Patterns for Common Use Cases
Email validation
// Basic — catches most invalid emails
const email = /^[^s@]+@[^s@]+.[^s@]+$/;
// More thorough (RFC 5322 subset)
const emailStrict = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
URL validation
const url = /^https?://(www.)?[-a-zA-Z0-9@:%._+~#=]{1,256}.[a-zA-Z0-9()]{1,6}([-a-zA-Z0-9()@:%_+.~#?&//=]*)$/;
Strong password check
// At least 8 chars, 1 uppercase, 1 lowercase, 1 digit, 1 special
const strong = /^(?=.*[a-z])(?=.*[A-Z])(?=.*d)(?=.*[!@#$%^&*]).{8,}$/;
IPv4 address
const ipv4 = /^(25[0-5]|2[0-4]d|[01]?dd?)(.(25[0-5]|2[0-4]d|[01]?dd?)){3}$/;
ISO 8601 date
const isoDate = /^d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]d|3[01])$/;
Performance Tips
- Compile once, reuse — in loops, define the regex outside the loop so it's compiled once:
const re = /pattern/g; - Avoid catastrophic backtracking — nested quantifiers like
(a+)+can cause exponential backtracking on certain inputs, hanging your application - Be specific —
d{4}is faster than.{4}because it restricts the match set - Anchor when possible —
^pattern$prevents the engine from searching the entire string for a partial match
Test Your Regex
Use the Copynix Regex Tester to build and test regular expressions in real time. Paste your pattern and test strings to see highlighted matches, capture group values, and match counts — instantly in your browser.
Summary
Regular expressions are one of the highest-leverage tools in a developer's arsenal. Mastering character classes, quantifiers, groups, and lookarounds opens up powerful text processing capabilities. Start with the practical patterns above and extend them for your specific validation and parsing needs.
