Docspira

JavaScript Regex Tester

Test a JavaScript regular expression against text and see exactly what matched, instantly in your browser. JavaScript (ECMAScript) syntax only, not PCRE, Python, .NET, Java, Ruby, or Go.

Uses native JavaScript replacement syntax: $& (whole match), $1, $2… (groups), $<name> (named group), $$ (literal $).

Your pattern, flags, test text and matches are processed in this browser and are never sent to Docspira. Learn more.

About this tool

This tool runs your pattern with the browser's own, unmodified JavaScript (ECMAScript) regular expression engine: the exact same engine and flags (g, i, m, s, u, y, d) your JavaScript code would use, nothing more and nothing less. It does not explain or diagram your regex, does not generate a regex from a description, and does not attempt to certify a pattern as safe from catastrophic backtracking; it only bounds how long a single test can run (the evaluation is isolated in a background worker with a timeout) and how many matches are shown at once (the first 1000). It is not a PCRE, Python, .NET, Java, Ruby, or Go regex tester; those flavors differ from JavaScript's in real, sometimes subtle ways.

What this tool does

Test JavaScript regular expressions against sample text.

How to use

  1. Enter a JavaScript regular expression and choose its flags.
  2. Paste sample text to test against it.
  3. Review matches, capture groups, and the replacement preview.

JavaScript regex cheat sheet

Pattern Matches
. Any character except line breaks (add the s flag to include them)
\d \w \s Digit, word character ([A-Za-z0-9_] only), whitespace
\D \W \S The opposite of each
[abc] [^abc] [a-z] Character set, negated set, range
^ $ Start and end of the input (of each line with the m flag)
\b Word boundary
* + ? {2,5} 0 or more, 1 or more, optional, between 2 and 5
*? +? Lazy versions: match as little as possible
(abc) Capture group, referenced as $1 in replacements
(?<year>\d{4}) Named group, referenced as $<year>
(?:abc) Group without capturing
a|b a or b
(?=x) (?!x) Lookahead: followed by x, not followed by x
(?<=x) (?<!x) Lookbehind: preceded by x, not preceded by x
\p{L} Any Unicode letter (requires the u flag)

What each flag does

Flag Name Effect
g global Find every match instead of stopping at the first. Required for matchAll and replace-all.
i ignore case a matches A.
m multiline ^ and $ match at every line break, not only at the start and end of the text.
s dotAll . also matches line breaks.
u unicode Treats emoji and other astral characters as one character, enables \p{...}, and makes invalid escapes an error.
y sticky Matches only at the exact position in lastIndex. Mostly useful for tokenizers.
d indices Adds start and end positions for the match and each group.

Gotchas that only bite in JavaScript

Each of these was checked against V8, the engine in Chrome and Node.js.

\w doesn't match accented letters. /\w+/g on São finds S and o. For any language other than plain English, use /\p{L}+/gu, which returns São.

. doesn't match emoji without u. /^.$/.test("😀") is false, because the emoji is two UTF-16 code units. With the u flag it's true.

test() with the g flag remembers where it stopped. Calling /a/g.test("a") three times on the same regex object gives true, false, true, because lastIndex moves forward after each match. Drop the g flag for yes/no checks, or reset lastIndex = 0.

matchAll throws without g. "aa".matchAll(/a/) raises a TypeError. Add the g flag.

Greedy by default. /<.+>/ on <b>x</b> matches the whole string. Use the lazy /<.+?>/ to match just <b>.

Features from other flavors are syntax errors here. These work in PCRE, Python or Java but not in JavaScript:

Written for another flavor In JavaScript
(?i)abc inline flags Invalid group. Use the i flag instead.
a++, a*+ possessive quantifiers Nothing to repeat.
(?>...) atomic groups Invalid group.
\A and \Z anchors Silently mean the letters A and Z without u; an error with u. Use ^ and $.
(?P<name>...) Python named groups Invalid group. Use (?<name>...).

Scoped modifiers are brand new. (?i:abc) (case-insensitive for just part of the pattern) was added in ES2025. Current Chrome and Firefox accept it; older browsers and Node.js 22 throw Invalid group. Don't rely on it for code that runs everywhere.

Replacement syntax

The Replacement box uses the same syntax as String.prototype.replace:

Token Inserts
$& The whole match
$1, $2... Numbered capture groups
$<name> A named group
$` and $' The text before and after the match
$$ A literal $

Example: pattern (?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2}), replacement $<d>/$<m>/$<y>, turns 2026-09-26 into 26/09/2026.

Catastrophic backtracking

Nested quantifiers like ^(a+)+$ can take exponential time when the input almost matches. Against a string of 26 a characters followed by !, that pattern took over 3 seconds in Node.js; every extra character roughly doubles it. That's why this tester runs your pattern in a background worker with a time limit: a slow pattern shows a timeout instead of freezing the page. If you hit it, remove the nesting (^a+$ means the same thing here) or make the alternatives mutually exclusive.

FAQ

Is my text sent anywhere?

No. The pattern runs in your browser with its built-in JavaScript regex engine. Nothing is uploaded, which makes it safe to test against log lines or real data.

Does this work for TypeScript regex?

Yes. TypeScript uses JavaScript's regex engine unchanged, so a pattern that works here works in TypeScript, in Node.js and in the browser.

Can I test Java, Python or PCRE regex here?

Only if the pattern avoids flavor-specific features. Basic syntax (classes, quantifiers, groups, lookahead) is shared. Inline flags, possessive quantifiers, atomic groups and \A/\Z are not; see the table above.

Why does my regex match in the tester but not in my code?

The usual causes: in a JavaScript string you must double the backslashes (new RegExp("\\d+"), not "\d+"); the flags differ between the tester and your code; or you reuse a g regex with test() (see lastIndex above).

How do I match across multiple lines?

Use the s flag so . matches line breaks, or [\s\S] in engines without s. If you want ^ and $ to match at each line, that's the m flag, which is a different thing.

JavaScript regex scope

The flags and JavaScript regex engine affect results; include edge-case samples before moving a pattern into production code.

Privacy

This tool runs in your browser; the text or file you choose is not uploaded for processing. Read the privacy details.