What Is a Regular Expression?
A regular expression — regex for short — is a compact pattern language for describing text. Where a plain search looks for an exact string, a regex describes the shape of a string: "five to eight digits", "a word character followed by an @", "a date in YYYY-MM-DD form". That power makes regex the backbone of text processing in every programming language, most editors (VS Code, Sublime, Vim), and command-line tools like grep and sed. Learning to read and write regex pays off across your entire toolchain.
The core building blocks are: literal characters (a matches "a"), metacharacters with special meaning (. matches any character, * and + are quantifiers), character classes that match one of a set ([\d._-] matches any digit, dot, underscore, or hyphen), anchors that fix a position (^ start, $ end), and groups that capture or group parts of a match. A pattern like ^[A-Z]\d{3}$ matches a single uppercase letter followed by exactly three digits and nothing else.
The Core Syntax, Explained
| Construct | Meaning | Example |
|---|---|---|
| \d | Any digit (0–9) | \d{3} |
| \w | Word character (letter, digit, underscore) | \w+ |
| \s | Whitespace (space, tab, newline) | \s+ |
| . | Any character except newline | a.c |
| * + ? | Zero+, one+, zero-or-one of the previous | colou?r |
| {n,m} | Between n and m repetitions | \d{2,4} |
| [abc] | One of the characters in the set | [aeiou] |
| ^ $ | Start / end of text (or line with m) | ^TODO |
| (…) | Capture group | (ab)+ |
| a|b | Alternation (a or b) | cat|dog |
| \b | Word boundary | \bcat\b |
Step-by-Step Example: Extracting Email Addresses
Let's say you have a block of support tickets and you want to pull every email address out of it. Paste the text into the tester and build the pattern up step by step.
- Start simple: the pattern \S+@\S+ matches any run of non-space characters around an @ — a first pass that catches most addresses.
- Tighten the local part: [\w.+-]+@\S+ restricts the part before @ to word characters, dots, pluses, and hyphens, which excludes trailing punctuation.
- Capture the pieces: ([\w.+-]+)@([\w.-]+) wraps each half in a capture group so you can see the username and domain separately.
- Check the highlights: the output marks each match, and the count in the summary tells you whether you caught them all or over-matched.
Try the final pattern against a paragraph containing a few emails and notice how the highlights track exactly what you asked for — and how quickly you can iterate when they don't.
Common Patterns Reference
| What It Matches | Pattern |
|---|---|
| US phone number | \(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4} |
| Date (YYYY-MM-DD) | \d{4}-\d{2}-\d{2} |
| Hex color code | #[0-9a-fA-F]{6}\b |
| Whole number | ^-?\d+$ |
| Decimal number | -?\d+(\.\d+)? |
| Whitespace runs | [ \t]+ |
| Trailing spaces | [ \t]+$ |
Troubleshooting & Practical Tips
Escape Metacharacters
The characters . * + ? ( ) [ ] { } ^ $ | \ all have special meaning. To match them literally, prefix with a backslash: a literal dot is \., a literal asterisk is \*, and a literal backslash is \\. Forgetting this is the single most common regex bug — "I searched for 3.5 and it matched 3x5".
Greedy vs. Lazy Quantifiers
Quantifiers are greedy by default: .+ matches as much as it can, so <.+> against "a <b> c <d>" matches the whole "<b> c <d>" rather than each tag. Adding a ? makes it lazy: <.+?> matches each tag individually. When your highlights look "too big", laziness is usually the fix.
Use Anchors to Avoid Partial Matches
A pattern like \d{3} matches the first three digits of "12345". When you want a whole thing and nothing more, anchor it — ^\d{3}$ for the entire text, or \b\d{3}\b for a three-digit token surrounded by word boundaries.
Common Mistakes to Avoid
- Forgetting to escape dots, pluses, and other metacharacters.
- Over-escaping in the tester — a slash inside the pattern field needs no backslash.
- Using $ to mean "end of line" without the m flag.
- Testing on tiny sample text and assuming it generalizes to real input.
- Ignoring capture groups when all you need is the matched text.