What a regular expression is
A regular expression (regex) is a search pattern written as text: instead of looking for one fixed word, you describe the shape of what you want — “three digits, a dash, four digits” — and the engine finds every piece of text that fits. Developers use regex to validate forms, extract data from logs and run find-and-replace across entire codebases. This tester runs your browser’s real JavaScript engine, so whatever works here behaves identically in your code.
How to use this tester
- Type the pattern without slashes: to try
/\w+/g, just type\w+. - Tick the flags you need;
g(global) starts enabled because that is what you want most of the time. - Paste your test text (up to 50,000 characters).
- Results update live: a match counter, the text with every match highlighted, and each match’s index, value and capture groups — numbered and named.
- If the pattern is invalid you get the engine’s syntax error; Copy regex puts the finished expression on your clipboard.
Essential syntax
| Token | Meaning |
|---|---|
. | any character except a newline |
* | zero or more repetitions |
+ | one or more repetitions |
? | zero or one repetition (or makes the previous quantifier lazy) |
\d | a digit 0-9 |
\w | letter, digit or underscore |
\s | whitespace: space, tab or newline |
^ | start of the text (or of each line with the m flag) |
$ | end of the text (or of each line with the m flag) |
[abc] | one character from the set; [^abc] negates it |
(...) | capture group |
{n,m} | between n and m repetitions, e.g. \d{2,4} |
Worked example
Let’s check emails with ^[^\s@]+@[^\s@]+\.[^\s@]+$. Piece by piece: ^ anchors to the start; [^\s@]+ demands one or more characters that are neither whitespace nor an at sign; @ is the literal at sign; then the same block again, an escaped dot \., the ending, and $ anchors to the end. Actual results from the JavaScript engine:
| Input | Match? |
|---|---|
dev.team@example.com | yes |
jane@company.io | yes |
jane@company | no — missing the dot and TLD |
two@@mail.com | no — the second at sign breaks the pattern |
bad address@mail.com | no — contains a space |
The flags, explained
g(global): find every match instead of stopping at the first one.i(case-insensitive):catalso matchesCATandCat.m(multiline):^and$anchor per line rather than per whole text.s(dotAll): the dot.also matches newline characters.u(unicode): work in code points — required for emoji and\p{L}classes.
The JavaScript flavor
Every language speaks a slightly different regex dialect. Modern JavaScript supports lookbehind — (?<=\$)\d+ grabs 45 out of $45 without capturing the symbol (supported by all current browsers) — and named groups. Run (?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2}) against Due date: 2026-07-07 and you get a match at index 10 with the groups year = 2026, month = 07 and day = 07 — far more readable than juggling $1, $2, $3.
Frequently asked questions
Why doesn’t my regex match anything?
Two usual suspects: the g flag is off (without it only the first match is reported) or a special character is not escaped. Searching for 3.14 unescaped also finds 3514, because . means any character; a stray ( or + makes the pattern invalid. Write them as \., \( and \+. Also check whether ^ and $ anchor more than you intended.
How do I validate an email or phone number?
Use a permissive pattern like the worked example above and accept a hard truth: a perfect email regex does not exist — RFC 5322 allows addresses no practical pattern can fully cover, so check the general shape and confirm with a real message. For a US-style phone number, ^\d{3}-\d{3}-\d{4}$ handles dashed input and ^\d{10}$ handles digits only.
What does greedy vs lazy mean?
Quantifiers are greedy by default: they grab as much as possible. On <b>bold</b> and <i>italic</i>, the pattern <.+> returns the entire string, because .+ stretches to the last >. Adding ? makes it lazy: <.+?> with the g flag returns <b>, </b>, <i> and </i>, taking the minimum each time.
How is this different from regex101?
regex101 is a great site with multiple flavors (PCRE, Python, Go) and a step-by-step debugger. This tester focuses on the JavaScript flavor and runs entirely client-side: neither your pattern nor your text ever leaves the device, which matters when testing against logs, tokens or customer data.