Regex Tester

Runs locally

Test JavaScript regular expressions with live highlighting, groups and replace.

Pattern

//gi

Running…

Test string

Cheat sheet

Click a token to insert it at the cursor. With text selected, groups wrap the selection.

Characters

Anchors

Quantifiers

Groups

Lookaround

JavaScript, not PCRE

Patterns run in your browser’s own JavaScript (ECMAScript) engine, so what matches here matches in Node, Deno and front-end code.

PCRE (PHP, grep -P, nginx), Python and Java differ. JavaScript has no possessive quantifiers (a++), atomic groups (?>…), recursion or \A and \Z anchors, and names groups (?<name>…) where Python uses (?P<name>…).

POSIX classes such as [[:alpha:]] are not supported; use \p{L} with the u flag.

Guide

Test the pattern in the engine that will run it

Regular expressions look the same across languages but are not. This tester runs your pattern in the browser’s own JavaScript engine (ECMAScript), so a match here is a match in Node.js, Deno, Bun and front-end code — including features that differ elsewhere, such as named groups written (?<name>…), lookbehind, the u flag for Unicode property escapes like \p{L}, and the d flag, which reports where each capture group starts and ends. The group table uses those positions, which is how it can show that group 2 of match 3 sits at characters 34–36.

Flags change how a pattern behaves more than most people expect. Without g only the first match is found — and only the first is replaced. m makes ^ and $ match at every line, s lets . cross line breaks, i ignores case, and y (sticky) only matches exactly where the previous match ended. An empty match, such as \d* at a position with no digits, is legal; the tester steps past it so the next search can continue. To clean up text after a replace, compare the before and after in the Diff Checker.

Some patterns take exponential time on inputs that almost match: (a+)+$ against a long run of a’s followed by ! tries every way of splitting the a’s before failing. That is catastrophic backtracking, the cause of real outages. Here the pattern runs in a Web Worker that is stopped after one second, with a note on what to look for: nested quantifiers and alternatives that can match the same text. The fix is to make each part unambiguous, for example ^a+$.

Pattern (g) and text

(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})

Released 2024-01-15, patched 2024-02-03

Matches and replace with $<day>/$<month>/$<year>

Match 1  2024-01-15  9–19   year=2024 month=01 day=15
Match 2  2024-02-03  29–39  year=2024 month=02 day=03

Released 15/01/2024, patched 03/02/2024

Positions are character offsets, end exclusive — the same numbers match.indices gives with the d flag.

Where people get caught

Forgetting the g flag

Without g, exec and replace stop after the first match. If only one date changed in a replace, the flag is missing.

Escaping in string literals

A pattern written in a JavaScript string needs double backslashes: new RegExp("\\d+"). The pattern box here takes the regex itself, as in a /…/ literal, so write \d+.

Greedy quantifiers matching too much

<.+> on "<a><b>" matches the whole string. Use the lazy <.+?> or a negated class <[^>]+> to stop at the first >.

Copying a PCRE or Python pattern

Possessive quantifiers (a++), atomic groups (?>…) and (?P<name>…) are errors in JavaScript. Rewrite them, or test in the engine that will run the pattern.

. does not match line breaks

Without the s flag, . stops at \n, so a pattern that works on one line fails on a pasted block. Add s or use [\s\S].

About regular expressions

How it works in 4 steps · 4 common use cases · 5 questions answered

How it works

  1. 1.Type a pattern and toggle flags; matches highlight as you type.
  2. 2.Read every capture group and its position in the table.
  3. 3.Switch to Replace to preview $1, $<name> and $& substitutions.
  4. 4.Click a cheat-sheet token to insert it at the cursor.

Common use cases

  • •Pulling IDs, emails or timestamps out of log lines
  • •Checking a validation pattern before it ships in a form
  • •Writing a search-and-replace for a refactor
  • •Finding out why a pattern hangs on some inputs

FAQ

Which regex flavour does this tester use?

JavaScript (ECMAScript), in your own browser. Results match Node.js and other JavaScript runtimes. PCRE, Python and Java share most syntax but differ in features such as possessive quantifiers, atomic groups and named-group syntax.

What does the d flag do?

It makes the engine record the start and end index of every capture group (match.indices). The group table here uses it to show where each group matched.

Why does my pattern time out?

It is backtracking catastrophically: nested or overlapping quantifiers such as (a+)+ or (\w|\d)* try exponentially many combinations on an input that almost matches. Rewrite it so each character can be matched only one way.

How do I use a capture group in the replacement?

Write $1, $2… for numbered groups, $<name> for named groups, $& for the whole match and $$ for a literal dollar sign.

Is my test text sent anywhere?

No. The pattern runs in a Web Worker inside this tab, and nothing you type leaves your browser.