Regex
Regular Expressions Guide: How Regex Works with Examples
Published 2026-08-15 · 10 min read
TL;DR: A regular expression is a pattern of literals and metacharacters that matches text; most patterns combine character classes such as \d, quantifiers such as +, and anchors.
A regular expression, or regex, is a tiny program written as text that describes a pattern of characters. You hand it a string, and it answers where the string matches the pattern. That one idea powers search in editors, validation in forms, parsing in scripts and extraction in pipelines, and the same syntax works, with small differences, in JavaScript, Python, Java and most other languages. The MDN regex guide is the reference this article follows.
How do you read a regular expression?
Read a pattern from left to right as a sequence of requirements. Most characters match themselves: the pattern cat matches the letters c-a-t wherever they appear in order. Metacharacters, shown below, break that rule and describe kinds of characters, counts or positions instead. The first skill in regex is separating the literal characters from the metacharacters in a pattern.
cat matches "cat" inside "concatenate"
car does not match "concatenate"
cat$ matches "cat" only at the end of a stringWhat are character classes?
Square brackets define a set of characters to match at that position. [aeiou] matches any single vowel, [a-z] matches any lowercase letter, and a leading caret negates the set, so [^0-9] matches any character that is not a digit. Shorthand classes shorten the common ones: \d matches a digit, \w a word character and \s a whitespace character, with uppercase forms meaning the opposite.
\d{4} four digits, e.g. 2026
[A-Z]{2} two uppercase letters
[^\s]+ one or more non-space charactersHow do quantifiers work?
Quantifiers say how many times the previous token may appear. The star * allows zero or more, the plus + requires one or more, the question mark ? makes it optional, and curly braces give exact ranges: {3} exactly three, {2,4} two to four, {2,} at least two. Without a quantifier, a token matches exactly once.
ab* matches a, ab, abb, abbb
ab+ matches ab, abb but not a
colou?r matches color and colour
\d{2,4} matches 42, 420, 4200What are anchors and word boundaries?
Anchors do not consume characters; they assert a position. The caret ^ matches the start of the string, the dollar $ matches the end, and \b matches a boundary between a word character and a non-word character. Anchors are what turn a search into a validation: the pattern ^\d+$ accepts only a string of one or more digits and nothing else.
^\d{4}$ the whole string is exactly four digits
\bcat\b matches cat but not category
^hello matches hello only at the startHow do groups and alternation work?
Parentheses group part of a pattern so a quantifier or alternation applies to the whole group, and alternation with the pipe | means or. The pattern (ab)+ matches ab, abab and ababab. Groups also capture the matched text, which is how you extract pieces of a match; details are in the guide to groups and capturing.
(ab)+ matches ab, abab
gray|grey matches gray or grey
gr(a|e)y same thing with a group
colou?r matches color and colourWhat are flags?
Flags change how the whole expression runs. The global flag g makes a search return every match instead of the first, i makes matching case-insensitive, m makes ^ and $ match at line breaks, s makes the dot match newlines too, and u switches to unicode mode, which is required for patterns that match emoji or astral characters.
/hello/i matches Hello, HELLO
/^test/gm matches test at the start of each line
/^.$/s matches a newline as the single characterHow do you test a pattern quickly?
The fastest loop is test, adjust, retest. The regex tester highlights matches live as you type both pattern and sample text, which is far faster than running a script for every small change. The regex builder assembles a pattern piece by piece when you are starting from nothing, and regex escape turns any string into a safely escaped literal for when you want to match text exactly.
What are the limits of regex?
Regex matches patterns of characters; it does not understand structure. Parsing HTML, JSON or a programming language with regex produces fragile code, because those formats nest and regex does not count depth. For real structure, use a real parser and keep regex for the text-level jobs it is good at. The email regex and URL regex guides show where a simple pattern is enough and where it is not.
Related Tools
Regex Tester
Test regex patterns against your text with live highlighting, capture groups and common-pattern shortcuts.
Regex Builder
Compose regular expressions from reusable blocks and watch matches highlight live against your test text.
Regex Escape Tool
Escape every regex metacharacter in a string so it matches literally inside a pattern.
Related Guides
Regex Cheat Sheet: Every Metacharacter Explained
A compact regex cheat sheet: anchors, character classes, quantifiers, groups, alternation and flags, with the meaning and an example for every common token.
Regex Groups and Capturing: How Grouping Works
Capturing groups, non-capturing groups, named groups and backreferences: what parentheses do in regex and how to extract pieces of a match.
Email Regex: How to Validate an Email Address
A practical email regex, why the full RFC 5322 pattern is a trap, and how to validate email in HTML5, JavaScript and Python without over-engineering.
URL Regex: How to Match and Validate a URL
Match and validate URLs with regex: protocol, host, path, query and fragment, plus practical patterns and when to use the URL API instead of a regex.
Frequently Asked Questions
What is a regular expression?
A regular expression, or regex, is a string that describes a pattern of text. Tools scan input and report every place the pattern matches, which makes regex the standard way to search, validate and extract from text.
Is regex the same in every language?
The core syntax is shared, but dialects differ. JavaScript, Python, Java and Go all support literals, classes, quantifiers and groups; features such as lookbehind and named groups have different support levels, so test a pattern in the engine you will ship.
Why does my regex match more than I expect?
Greedy quantifiers such as .* consume as much as possible. Use a lazy form such as .*? or a negated class such as [^"]* to make the match stop sooner, and add anchors to bound where the match can start.
Do I need to escape every special character?
Only metacharacters, which are . ^ $ * + ? ( ) [ ] { } | and the backslash itself. Inside a character class, the set of characters that need escaping is smaller, and a literal hyphen can go at the start or end of a class.
How do I learn to write a pattern for my data?
Start from the simplest pattern that works, then add constraints one at a time. A [regex tester](/tools/regex-tester) shows matches live, which makes it fast to try a small change and see what happens.