Quick answer: A regular expression is a pattern that describes text, such as "five digits" or "a word at the start of a line". You build it from literal characters, character classes, quantifiers and anchors, then test it against real sample text before putting it in code. This guide uses the JavaScript (ECMAScript) flavor, which is what the Regex Tester runs.
Try the free Regex Tester
Free, no sign-up, and built by the author of this guide.
Open the Regex TesterThe building blocks
| Syntax | Matches | Example |
|---|---|---|
abc | The literal characters | cat matches "cat" in "concatenate" |
. | Any character except a line break | c.t matches "cat" and "cut" |
\d \w \s | Digit, word character (letter, digit, underscore), whitespace | \d\d matches "42" |
[aeiou] [^0-9] | One character from a set, or not in a set | gr[ae]y matches "gray" and "grey" |
* + ? | Zero or more, one or more, zero or one | colou?r matches both spellings |
{n,m} | Between n and m repetitions | \d{3,4} matches 3 or 4 digits |
^ $ \b | Start, end, word boundary | ^ERROR matches only at the start |
( ) | | Group, alternation | (jpg|png) matches either |
\. | A literal special character | example\.com |
Characters with special meaning, . * + ? ^ $ { } ( ) [ ] | \, need a backslash when you mean them literally.
Flags in JavaScript regex
Flags change how the whole pattern behaves. The ECMAScript specification defines these:
g: global, find every match instead of stopping at the first.i: ignore case.m: multiline, so^and$match at the start and end of each line.s: dotAll, so.also matches line breaks.uandv: Unicode modes, needed for\p{L}property escapes;vis the newer, stricter mode.y: sticky, match only at the current position.d: record start and end indices for capture groups.
Other engines such as PCRE, Python and .NET share most basic syntax but differ in details, so a pattern tested as JavaScript may need changes elsewhere. For the full JavaScript syntax, see the MDN regular expressions guide.
Worked example: finding order numbers
You want order numbers like ORD-12345 from this text:
Orders ORD-12345 and ORD-98765 shipped; ord-55555 was cancelled.
Use the pattern \bORD-\d{5}\b: a word boundary, the literal ORD-, exactly five digits and another word boundary.
- With flags
g: 2 matches,ORD-12345at index 7 andORD-98765at index 21. - With flags
gi: 3 matches, becauseord-55555at index 40 also matches when case is ignored.
The index is the zero-based position of the first character of the match. The \b at the end matters: without it, the pattern would also match the first five digits of ORD-123456.
How to use the free Regex Tester
- Type the pattern into the Pattern field without surrounding slashes. Enter
\bORD-\d{5}\b, not/\bORD-\d{5}\b/; slashes would be matched as literal characters. - Set the Flags field. It starts as
gi, so matching ignores case by default. Removeifor a case-sensitive test. - Paste real sample data into Test text, including lines that should not match.
- Select Test expression. The result shows the number of matches and a numbered list of each matched text with its index.
- If the pattern or a flag is invalid, "Invalid expression" appears with your browser's error message, such as an unterminated group.
The tester runs your browser's own JavaScript engine. It lists every match even if you leave out g, shows at most the first 100, and shows whole matches only, not the text inside each capture group.
Moving a tested pattern into code
A regex literal in JavaScript is written between slashes: /\bORD-\d{5}\b/g. If you build it from a string with new RegExp(), or store it in JSON or a double-quoted YAML string, each backslash must be doubled, as in "\\bORD-\\d{5}\\b". A single backslash in a string is consumed as an escape character before the regex engine sees it.
Common mistakes
- Greedy matching. In
"title": "a", "id": "b", the pattern".*"returns one match covering the whole line, because*takes as much as it can. The lazy version".*?"returns four separate quoted strings. - Unescaped dots.
example.comalso matchesexampleXcom; useexample\.com. - Missing anchors. When validating a whole value, wrap the pattern in
^and$, or\d{5}acceptsabc12345xyz. - Forgetting case. Results differ between
gandgi, as the worked example shows. - Nested quantifiers. Patterns like
(a+)+$can take an extremely long time on input that almost matches. Avoid them on untrusted input.
Frequently asked questions
Which regex flavor does the Regex Tester use?+
It uses JavaScript (ECMAScript) regular expressions, run by your browser's engine. Most basic syntax works the same in other languages, but check details such as lookbehind and named groups in your target engine.
Why does my pattern match in the tester but not in my code?+
The most common causes are different flags, such as the tester's default i flag, and single backslashes inside a string literal. Compare the flags and double the backslashes when the pattern is in a string.
What is the difference between greedy and lazy quantifiers?+
Greedy quantifiers such as * and + match as much text as possible, while lazy versions such as *? and +? match as little as possible. Use lazy quantifiers when a pattern overruns the text you want.
Can I use regex to validate email addresses?+
Only loosely. A simple pattern can catch obvious typos, but the full address syntax is too complex for a practical regex, so the reliable check is sending a confirmation email.
Is my test text sent to a server?+
No. The Regex Tester runs the pattern with your browser's JavaScript engine, so the pattern and the sample text stay on your device. You can still remove sensitive values from logs before pasting them, as a habit.