DEVELOPER TOOL

Regex Tester and JavaScript Cheat Sheet

Test a JavaScript regular expression against sample text and see every match highlighted live, with a regex cheat sheet and tested examples below.

About this regex tester

This regex tester runs your pattern with the browser's own JavaScript RegExp engine, so results match what you get in browser code or Node.js. It builds the expression with new RegExp(pattern, flags), adds the g flag if you left it out, and walks every match with String.prototype.matchAll(). Each match is highlighted and counted, and your text is inserted as plain text, so HTML in it is shown, never run. Nothing is uploaded.

How to use it

  1. Enter a pattern without the surrounding slashes: \d+, not /\d+/.
  2. Set flags such as i, m or s. g is always applied.
  3. Paste sample text. Matches highlight as you type, and the count shows above the result.

Worked example

The sample uses the pattern \bcolou?r\b with flags gi on three lines of text. The count is 3: Color, colour and COLOR. The ? makes the u optional, i ignores case, and the two \b word boundaries reject colors and colorful, where a letter follows the r. Delete the final \b and the count rises to 5.

JavaScript regex cheat sheet

Checked against the MDN regular expression cheat sheet and tested in this page's engine.

SyntaxMeaning
.Any character except a line break (with s, line breaks too)
\d \w \sDigit 0–9; word character [A-Za-z0-9_]; whitespace, including Unicode spaces
\D \W \SThe opposite of each
[abc] [^abc] [a-z]One character from the set; not in the set; in the range
\t \n \rTab, line feed, carriage return
\u{1F600} \p{L}Code point escape and Unicode property; need u or v
^ $Start and end of input (of each line with m)
\b \BWord boundary; not a word boundary
* + ?0 or more; 1 or more; 0 or 1
{3} {3,} {3,5}Exactly 3; 3 or more; 3 to 5
*? +? ??Lazy versions: as few as possible
(x) \1Capturing group; backreference to group 1
(?:x)Group without capturing
(?<year>\d{4}) \k<year>Named group, read as match.groups.year; named backreference
a|ba or b
x(?=y) x(?!y)x only if followed (not followed) by y
(?<=y)x (?<!y)xx only if preceded (not preceded) by y

All eight JavaScript regex flags

FlagNameWhat it does
dhasIndicesRecords the start and end positions of each capture group
gglobalFinds all matches instead of stopping at the first
iignoreCaseIgnores the difference between upper and lowercase
mmultilineMakes ^ and $ match at the start and end of each line
sdotAllLets . match line breaks
uunicodeTreats the pattern as Unicode code points, enabling \u{…} and \p{…}
vunicodeSetsAn upgrade to u with more Unicode features; can't be combined with u
ystickyMatches only at the current position, not anywhere later

An unknown letter, or the same flag twice, makes the pattern invalid, and the tester shows the browser's error message. One trap: without u or v, \p{L} is not an error. It quietly matches the literal text p{L}.

Regex examples, with honest caveats

UsePatternCaveat
Whole number^-?\d+$Rejects +1 and 1,000
US ZIP code^\d{5}(-\d{4})?$Checks the format, not that the ZIP exists
US phone^\(?\d{3}\)?[-. ]?\d{3}[-. ]?\d{4}$Also accepts an unbalanced (555-123-4567
Date YYYY-MM-DD^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$Accepts 2026-02-31; check real dates in code
Email (rough)^[^\s@]+@[^\s@]+\.[^\s@]+$Accepts a@b..c, rejects ana@localhost; only sending mail proves an address
Hex color^#([0-9a-fA-F]{3}){1,2}$Ignores 4- and 8-digit forms with alpha
IPv4 address^((25[0-5]|2[0-4]\d|1?\d?\d)\.){3}(25[0-5]|2[0-4]\d|1?\d?\d)$Allows leading zeros such as 01
Repeated word\b(\w+)\s+\1\b with iFinds is is and the THE

With m off, ^ and $ anchor to the whole text, so validation patterns like these match only when the box holds a single value. Turn on m to test one value per line.

Catastrophic backtracking

A backtracking engine like JavaScript's tries alternatives one by one. Nested quantifiers over the same characters make that explode. Test ^(a+)+$ against 25 letters a followed by b: the match must fail, but first the engine tries every way to share the a's between the inner and outer +, and 25 a's can be split 224 = 16,777,216 ways. Each extra a doubles the work. In our test in Node.js 22, which uses the same V8 engine as Chrome, 26 a's took about 0.4 seconds; a few more freeze the tab. This page matches as you type, so try such patterns on short text. The fix is to remove the ambiguity: ^a+$ answers the same question instantly. JavaScript has no atomic groups or possessive quantifiers; a++ is a syntax error, so rewriting is the only option.

How JavaScript regex differs from PCRE and Python

Characters that need a backslash

To match these literally, escape them with \: . * + ? ^ $ { } ( ) | [ ] \, and - inside a character class. The classic bug is example.com, whose dot also matches examplexcom; write example\.com. In a JavaScript string for new RegExp(), double every backslash: "\\d+".

Zero-length matches and a surprising count

A pattern that can match nothing, such as \d*, matches an empty string wherever the real match fails. Against ab12 the count is 4, not 1: empty matches before a and b, the real 12, and one at the end. Use + instead of * to require a character.

Once a pattern works, run it on real text with Find & Replace, which supports regex and capture groups, or tidy the text first with the Text Cleaner so stray spaces and line breaks don't hide matches.

Frequently asked questions

Which regex flavor does this tool use?

This tool uses JavaScript's native RegExp engine (ECMAScript regex), so patterns behave exactly as they do in a browser console or Node.js. Most syntax is shared with PCRE and Python, but named group syntax, lookbehind rules, possessive quantifiers and what $ and \d match differ, so test in your target language too.

What do the g, i, m, and s flags do?

g finds all matches instead of stopping at the first one, i makes matching case-insensitive, m makes ^ and $ match the start/end of each line instead of the whole string, and s lets . match newline characters too.

Why does my pattern show 0 matches even though I can see a match by eye?

This tester always searches for every match (it adds the g flag automatically if you leave it out), so the most common causes are an unescaped special character like a literal period or parenthesis, case sensitivity when the i flag isn't set, or ^ and $ matching only the start and end of the whole text when the m flag isn't set.

Can a regex validate an email address?

Only roughly. A simple pattern such as ^[^\s@]+@[^\s@]+\.[^\s@]+$ catches obvious typos, but it accepts some invalid addresses and rejects some valid ones, and no pattern can tell whether a mailbox exists. Use a regex for a quick format check, then confirm the address by sending a message to it.

Is my test text sent anywhere?

No. Matching runs entirely in your browser using JavaScript's built-in RegExp object — nothing is uploaded or logged.

What does the y (sticky) flag do in JavaScript regex?

The sticky flag makes the regex match only at the exact position given by its lastIndex property, rather than searching ahead through the rest of the string. It is mainly used when writing tokenizers or parsers that read input step by step. Combined with g, as here, matches must follow each other with no gaps.

Why is the match count higher than the highlighted matches?

Your pattern can probably match an empty string, for example because it uses * or ? on everything. JavaScript then records an empty match at every position where nothing longer matches, and each one is counted even though there is nothing to highlight. Requiring at least one character, with + instead of *, usually fixes it.

Why does my regex freeze the page?

It is probably catastrophic backtracking. Nested quantifiers such as (a+)+ give the engine an exponential number of ways to try before a match can fail, so each extra character can double the time. Rewrite the pattern so each part of the text can be matched only one way, and test it on short text first.