Regex Tester
Match · Groups · Replace · Explain
Flags
Type a pattern above.

What the pattern means

  • The explanation appears here.

No matches yet.

How to use this regex tester

  1. Type the pattern between the two slashes, without the slashes themselves. If you paste a full literal such as /\d+/gi, the tester splits it into the pattern and the flags for you.
  2. Choose the flags. g is on by default so you see every match. Turn on i to ignore case and m when ^ and $ should work per line.
  3. Paste your text. Matches are highlighted in two alternating colours so that matches next to each other stay apart. An empty match is shown as a thin yellow line.
  4. Read the results. The Matches tab lists every match with its position (line and column) and the text of each capture group. What the pattern means explains every token in plain English, which is the fastest way to find a mistake.
  5. Replace shows the text after a search and replace, with $1 or $<name> for groups. Code writes the pattern for JavaScript, Python, Java, C#, PHP or Go.
  6. Copy link saves the pattern, flags and text in a link you can share or bookmark.

The tester uses your browser's JavaScript engine and runs every pattern in a background worker. A pattern that runs for more than 2 seconds is stopped, so a runaway regex can never freeze the page. Nothing you type is uploaded.

Regex cheat sheet

Characters and classes

.Any character except a line break (with s: any character)
\d \DA digit 0–9 / anything else
\w \WA word character A–Z, a–z, 0–9, _ / anything else
\s \SWhite space (space, tab, line break) / anything else
[abc]One of a, b or c
[^abc]Any character except a, b and c
[a-z0-9]A character in a range
\. \\ \(A literal dot, backslash, bracket
\n \t \rLine feed, tab, carriage return
\u00e9 \p{L}A Unicode character / any letter (with u)

Anchors and quantifiers

^ $Start / end of the text (with m: of each line)
\b \BA word boundary / not a word boundary
*0 or more times
+1 or more times
?0 or 1 time (optional)
{3}Exactly 3 times
{2,} {2,5}2 or more / 2 to 5 times
*? +? {2,5}?Lazy: as few times as possible

Groups and lookaround

(abc)Capture group (numbered from 1)
(?<year>\d{4})Named capture group
(?:abc)Group without capturing
a|ba or b
\1 \k<year>The same text that group 1 / group year matched
x(?=y) x(?!y)x followed by y / not followed by y
(?<=y)x (?<!y)xx preceded by y / not preceded by y

Replacement tokens (JavaScript)

$1 $2Text of group 1, group 2
$<name>Text of a named group
$&The whole match
$` $'The text before / after the match
$$A literal $

Common regular expressions, explained

All of these are in the Common patterns list above, with sample text, so you can try and change them.

WhatPatternNotes
Email address[\w.+-]+@[\w-]+(?:\.[\w-]+)+Good for finding addresses in text. The only real check is sending a mail.
URLhttps?:\/\/[^\s/$.?#][^\s]*http and https links up to the next space.
IPv4 address\b(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\bEach part is 0–255, so 256.1.1.1 does not match.
Date (ISO 8601)\b\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])\bChecks the month and day ranges, not leap years.
Time 24 h\b(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d)?\bHH:MM with optional seconds.
Hex colour#(?:[0-9a-fA-F]{3}){1,2}\b#fff and #3b82f6.
UUID\b[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\bUse with i. Versions 1–8. Make one with the UUID generator.
Repeated word\b(\w+)\s+\1\bFinds "the the". \1 repeats what group 1 matched.
Strong password^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\w\s]).{8,}$Each lookahead checks one rule without moving forward.

Regex in other languages

The core syntax (\d, [a-z], *, groups, |) is the same almost everywhere. These are the differences that cause most surprises:

LanguageFind all matchesNamed groupWatch out for
JavaScripttext.matchAll(/re/g)(?<n>…)matchAll and replaceAll need the g flag
Pythonre.findall(r"re", text)(?P<n>…)\d also matches non-ASCII digits; replacement uses \1
Javawhile (m.find())(?<n>…)Every backslash is doubled in a string: "\\d+"
C# / .NETRegex.Matches(text, @"re")(?<n>…)RegexOptions.Singleline is the s flag
PHP (PCRE)preg_match_all('/re/', $text, $m)(?<n>…)The pattern needs delimiters; escape / inside
Go (RE2)re.FindAllString(text, -1)(?P<n>…)No lookaround and no backreferences, but never slow
grepgrep -E 're' file—Use grep -P for \d and lookaround

Frequently asked questions

Which regex flavor does this tester use?

It uses the JavaScript (ECMAScript) engine of your browser, the same one that runs RegExp in Chrome, Firefox, Safari and Node.js. Most simple patterns work the same in Python, Java, C#, PHP (PCRE) and Go. The differences are mostly in named groups, lookbehind, possessive quantifiers and flags; the Code tab writes the pattern in the right form for each language and warns about the rest.

Why does my regex match too much?

Quantifiers such as * and + are greedy: they take as much text as they can. In <b>bold</b> and <b>more</b>, the pattern <b>.*</b> matches from the first <b> to the last </b>. Add a ? to make it lazy (.*? takes as little as possible), or use a negated class such as [^<]* that cannot run past the next tag.

How do I match a dot, a plus or a bracket literally?

Put a backslash before it: \. matches a real dot, \+ a plus sign and \( a bracket. The characters that need it are . * + ? ^ $ { } ( ) [ ] | \ and, in a JavaScript literal, /. Inside a character class most of them are literal anyway, so [.+] matches a dot or a plus.

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

g (global) finds all matches instead of only the first. i ignores upper and lower case. m (multiline) makes ^ and $ match at the start and end of every line. s (dotAll) lets . match line breaks too. u (unicode) reads the pattern as Unicode code points and allows \p{...} classes. y (sticky) only matches exactly at the current position.

Why does my regex freeze or take forever?

This is called catastrophic backtracking. Nested quantifiers such as (a+)+ or (\w+\s?)*$ can try an exponential number of ways to split the text before they fail. Make each part match only one way: remove the nested quantifier, use a more specific class, or anchor the pattern. This tester runs the regex in a background worker and stops it after 2 seconds, so the page never hangs.

How do I use capture groups in a replacement?

In JavaScript, $1, $2 and so on insert the text of the numbered groups, $<name> inserts a named group, $& the whole match and $$ a literal dollar sign. For example (\d{4})-(\d{2})-(\d{2}) with the replacement $3.$2.$1 turns 2026-10-17 into 17.10.2026. Python uses \1 or \g<name> instead.

Is my text sent to a server?

No. The pattern and the test text are processed only in your browser. Nothing is uploaded or stored. The Copy link button puts the pattern and text into the part of the URL after #, which browsers never send to a server.

More developer tools