Skip to content

Regex Tester: Test JavaScript Regular Expressions

Regex tester for JavaScript: highlight matches live, inspect capture groups and named groups, try find-and-replace, and see clear error messages.

By Updated Runs in your browser

Regex Tester guide

Type a regular expression and some test text to see every match highlighted as you type, with the index and capture groups for each match and an optional replace preview. Uses your browser's own JavaScript regex engine.

How this regex tester works

Your pattern and flags are passed to new RegExp(pattern, flags), exactly what JavaScript code does at runtime, so what matches here matches in Chrome, Firefox, Safari, Node.js, and Deno. There is no server and no translation layer. If the pattern is invalid, the browser's own error message appears, such as "Unterminated group" or "Nothing to repeat".

Matches are highlighted in the text, listed with their starting index, and broken down by capture group and named group. Empty matches (for example from a pattern like a*) are listed but not highlighted. Results cap at 1,000 matches to keep the page responsive. Fill in the Replace field to preview String.prototype.replace with the same pattern and flags.

Worked example: pulling emails out of text

The default pattern is [\w.+-]+@([\w-]+\.)+[a-z]{2,} with flags gi. Read it left to right: one or more word characters, dots, plus signs, or hyphens; an @; one or more domain labels each followed by a literal dot; then a top-level domain of at least two letters.

Against the sample text it finds [email protected] and [email protected]. It correctly skips user@localhost (no dot and TLD), @handle (nothing before the @), and name@site. (the trailing dot has no TLD after it). Group 1 shows the last domain label it captured, such as example., because a repeated group only keeps its final repetition. That catches people out constantly.

Now try a replace: put [redacted] in the Replace field and both addresses are swapped out, a quick way to scrub a log file before sharing it.

Patterns worth keeping

US ZIP code: ^\d{5}(-\d{4})?$ matches 90210 and 90210-1234. US phone number, loosely: ^\(?\d{3}\)?[-. ]?\d{3}[-. ]?\d{4}$ matches (555) 123-4567, 555.123.4567, and 5551234567. ISO date: ^(?<year>\d{4})-(?<month>0[1-9]|1[0-2])-(?<day>0[1-9]|[12]\d|3[01])$ captures year, month, and day as named groups.

Hex color: ^#([0-9a-f]{3}|[0-9a-f]{6})$ with the i flag. Trailing whitespace on every line: [ \t]+$ with the gm flags. Duplicate consecutive words: \b(\w+)\s+\1\b with gi, which finds typos like "the the".

These are validation helpers, not proof of validity. A regex can confirm a ZIP code has five digits; it cannot tell you the ZIP exists. For email, the only real test is sending a confirmation message.

Anchors, lines, and the m flag

^ and $ match the start and end of the whole string by default. Add m and they match at the start and end of every line, which is what you usually want when testing a multi-line list. Validation patterns for a single input field should use ^ and $ without m, or a sneaky second line can slip past.

The dot matches any character except line breaks. Add the s flag, or use [\s\S], when a match needs to span lines, for example capturing an HTML comment.

Word boundaries deserve a mention here too. \b matches the position between a word character and a non-word character, so \bcat\b finds cat in "the cat sat" but not in "concatenate". In JavaScript, word characters are only A to Z, a to z, 0 to 9, and underscore, and \b keeps that definition even with the u flag, so accented letters like é count as boundaries. For Unicode text, build your own boundary with lookarounds and a property escape such as (?<!\p{L})cat(?!\p{L}) plus the u flag.

Common regex mistakes

Forgetting to escape the dot. example.com as a pattern also matches exampleXcom. Write example\.com.

Catastrophic backtracking. Nested quantifiers such as (a+)+$ or (\w+\s?)*$ can take exponential time on inputs that almost match, freezing a browser tab or taking down a server. This class of bug is called ReDoS, and it has caused real outages, including a 27-minute Cloudflare outage in July 2019. Keep quantifiers unambiguous and avoid nesting them.

Using a regex to parse HTML or JSON. It works for a quick one-off extraction, but for anything real, use DOMParser or JSON.parse. Nested structures are exactly what regular expressions cannot handle reliably.

Double escaping in code. In a JavaScript string, "\d" is just d. Either use a regex literal like /\d+/ or write "\\d+" in the string passed to new RegExp.

How we calculate: sources

Frequently asked questions

Which regex flavor does this tester use?

JavaScript (ECMAScript), run by your browser's engine. Most syntax matches PCRE, Python, and Java, but lookbehind support, named group syntax, and flags differ slightly, so test in the language you will ship.

What do the regex flags g, i, m, s, u, and y mean?

g finds all matches instead of the first, i ignores case, m makes ^ and $ match at each line, s lets . match newlines, u enables full Unicode, and y (sticky) matches only at the current position. d adds match indices and v enables newer Unicode set syntax.

Why does my regex only find one match?

The g flag is missing. Without it, JavaScript stops after the first match. Add g in the flags box to find every occurrence.

How do I match a literal dot, question mark, or bracket?

Escape it with a backslash: \. matches a period, \? a question mark, and \[ a bracket. The characters that need escaping are . * + ? ^ $ { } ( ) | [ ] \ and /.

What is the difference between greedy and lazy quantifiers?

Greedy quantifiers like .* grab as much as possible, then back off. Lazy ones like .*? grab as little as possible. On <b>a</b><b>b</b>, <b>.*</b> matches the whole string while <b>.*?</b> matches each tag pair separately.

How do I use capture groups in a replacement?

Wrap part of the pattern in parentheses and refer to it as $1, $2, and so on in the Replace field. Named groups written as (?<year>\d{4}) can be referenced as $<year>. $& inserts the whole match.

Is my test text uploaded?

Everything runs in your browser. Nothing you enter is uploaded to a server or stored by us.

Does JavaScript regex support lookbehind?

Yes. Lookbehind, (?<=...) and (?<!...), is supported in all current browsers, including Safari since version 16.4 (2023). Older Safari versions throw a syntax error.

How do I make a regex case-insensitive?

Add the i flag. In the flags box type i, or gi to also find every match rather than just the first.