Regex Tester

Regex Tester

Type a regular expression and some text to see every match highlighted, with each capture group listed, or switch to Match and replace to try a substitution. It uses JavaScript’s own regex engine — the one your browser runs — and nothing you type leaves this page.

Without the slashes: \d+, not /\d+/.
g all matches · i ignore case · m multiline · s dot matches line breaks · u Unicode · v Unicode sets · y sticky · d indices
Mode
Regex literal/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/g
In JavaScript codenew RegExp("(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})", "g")
Flagsall matches (g)
Capture groups3
Named groupsyear, month, day

Calculated on your device · formulas checked against known results · How we test

How to use the regex tester

  1. Type your regular expression without the slashes around it — \d+, not /\d+/.
  2. Add flags in the box beside it, such as g to find every match or gi to ignore upper and lower case as well.
  3. Paste the text to test. Every match is highlighted in the text, and a table lists each match with its position and what every capture group took.
  4. Try a replacement: choose Match and replace and write the new text, using $1 or $<name> for groups. The result appears above the matches with a Copy button.
  5. Take the pattern to your code: the results show it as a regex literal and as new RegExp(…) with the backslashes already doubled for a string.

If the pattern has a syntax error, you get the problem in plain words with a fix, followed by the browser’s own message.

Which regex flavor this is

Regular expressions come in dialects. This tester runs your pattern on the JavaScript engine of your own browser — V8 in Chrome and Edge, SpiderMonkey in Firefox, JavaScriptCore in Safari — which all follow the ECMAScript standard. So a pattern that works here works the same in JavaScript, TypeScript and Node.js. Most syntax is shared with PCRE (PHP, R), Python’s re, Java and .NET, but some things differ:

FeatureJavaScript (this tester)PCRE and Python
Lookbehind (?<=…) (?<!…)Supported, of any lengthSupported; Python needs a fixed width
Named groups(?<name>…), \k<name>, $<name> in a replacementPython writes (?P<name>…) and \g<name>
Possessive a++ and atomic groups (?>…)Not supportedPCRE: yes; Python: since 3.11
\d, \w, \bASCII only, even with the u flag: \d is 0–9Python 3: Unicode digits and letters by default
Unicode properties \p{L}With the u or v flagPCRE: yes; Python’s re: no
$ at the endOnly at the very end (or each line end with m)Also just before a final line break
Inline flags (?i)Not for the whole pattern; the newest browsers accept (?i:…) for a partSupported
\A, \Z, recursion, conditionalsNot supportedPCRE: yes

Without the u or v flag, JavaScript quietly reads an unknown escape as the plain letter, so \A matches “A” and \p{L} matches “p{L}”. The tester warns about both.

Regex cheat sheet

Characters and classes

SyntaxMatches
.Any character except a line break (any at all with the s flag)
\d \DA digit 0–9 / anything else
\w \WA letter, digit or underscore (A–Z, a–z, 0–9, _) / anything else
\s \SA space, tab or line break / anything else
[abc]One of a, b or c
[^abc]Any character except a, b and c
[a-z0-9]A range: a lowercase letter or a digit
\p{L} \p{N}Any letter / number in any script (u or v flag)
\. \* \\A literal dot, asterisk, backslash: a backslash escapes . * + ? ^ $ ( ) [ ] { } | \ /

Anchors

SyntaxMatches
^Start of the text (of each line with m)
$End of the text (of each line with m)
\bA word boundary, between \w and \W
\BNot a word boundary

Quantifiers

SyntaxMatches
*Zero or more times
+One or more times
?Zero or one time (optional)
{3}Exactly 3 times
{2,5}2 to 5 times
{2,}2 or more times
*? +? ??Lazy: as few times as possible instead of as many

Groups and lookarounds

SyntaxMatches
(abc)A capture group, numbered from 1 by its opening bracket
(?<name>abc)A named capture group
(?:abc)A group that doesn’t capture
\1 \k<name>The same text as group 1 / the named group matched
a|ba or b
(?=abc) (?!abc)Followed by abc / not followed by abc (lookahead)
(?<=abc) (?<!abc)Preceded by abc / not preceded by abc (lookbehind)

Replacement

SyntaxMatches
$1 $<name>The text of group 1 / of the named group
$&The whole match
$` $'The text before / after the match
$$A dollar sign

Ready-made patterns

Copy one into the box and adjust it. The last column is what each finds in the example, worked out by the tester’s own code.

ForPatternFlagsIn the exampleNotes
Email address (practical)[\w.+-]+@[\w-]+(?:\.[\w-]+)+gWrite to ana.lopez+news@mail.example.com or bo@shop.io. → ana.lopez+news@mail.example.com, bo@shop.ioFinds ordinary addresses in text. It isn’t a full RFC 5322 check — no practical regex is — so the only real test of an address is an email sent to it.
Web address (URL)https?:\/\/[^\s<>"]+gDocs at https://example.com/guide?page=2 and http://test.org/a. → https://example.com/guide?page=2, http://test.org/a.Runs until a space, quote or angle bracket, so a period right after a link is taken along.
Date as YYYY-MM-DD\b\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])\bgShipped 2026-10-16, returned 2026-13-01. → 2026-10-16Checks that the month is 01–12 and the day 01–31, not the calendar: 2026-02-30 passes.
US phone number\(?\b\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}\bgCall (202) 555-0143 or 202.555.0199. → (202) 555-0143, 202.555.0199Brackets, spaces, dots and dashes are optional.
Phone digits, any country\+?\d[\d\s().-]{6,}\dgWhatsApp +44 20 7946 0000, office 030 1234567. → +44 20 7946 0000, 030 1234567At least 8 digits with the usual separators; check the country rules separately.
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)\bgRouter 192.168.1.254, not 300.1.1.1. → 192.168.1.254Each of the four numbers must be 0–255, without leading zeros.
Hex color#(?:[\da-fA-F]{3}){1,2}\bgcolor: #1f4e79; border: #ccc; → #1f4e79, #cccThree or six hexadecimal digits.
Repeated word\b(\w+)\s+\1\bgiIt was the the best of of times. → the the, of of\1 repeats whatever group 1 matched; the i flag also catches “The the”.

Worked example

The sample pattern in the box, (?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2}), finds dates written as year-month-day. \d{4} is exactly four digits, and each part sits in a named group. With the g flag it finds 3 dates in the sample text: 2026-10-16 at position 27, 2026-11-15 at position 52, 2026-09-30 at position 86. Positions count from 0, so position 27 means 27 characters come before the match.

In Match and replace mode the replacement $<day>/$<month>/$<year> puts the day first, and the text becomes: “Invoice 1042 was issued on 16/10/2026 and is due on 15/11/2026.” Without the g flag only the first date would change.

Catastrophic backtracking

When a match fails, the engine goes back and tries the other ways the pattern could have matched. Usually there are few. But a repetition inside a repetition — (a+)+, (\w*)*, (a|aa)+ — can split the same text in an exponential number of ways. Testing (a+)+$ on 30 a’s followed by “!” means trying about 230, over a billion, splits before the engine gives up; each extra “a” doubles the time.

A regex can’t be interrupted in JavaScript, so in many testers such a pattern freezes the tab. Here it runs in a separate background thread (a Web Worker): after one second the tester stops it, says why, and points at the nested repetition if it finds one. The fix is to make every piece of text matchable in only one way — a+$ instead of (a+)+$, or a character class that excludes the separator, such as [^,]* instead of .*. The same pattern in a web server can be a denial-of-service risk (ReDoS), so it is worth fixing, not just avoiding.

Tips and limits

Privacy

Matching runs in your browser. The pattern and the text are never uploaded or logged. The page remembers your last inputs on this device so they are still there when you come back, and Copy link puts them after the # of the link, a part browsers never send to a server.

Frequently asked questions

Which regex flavor does this tester use?

JavaScript’s, as defined by the ECMAScript standard and built into every browser. Patterns behave exactly as in JavaScript, TypeScript and Node.js. For PHP, Python or Java most syntax is the same; the differences are listed above.

Why does my regex work in Python or PHP but not here?

Usually because of syntax JavaScript doesn’t have: (?P<name>…), possessive quantifiers such as a++, atomic groups, (?i) at the start, or \A and \Z. The error message names the problem, and for Python and PCRE syntax it shows the JavaScript way to write it.

How do I match a dot, a bracket or another special character?

Put a backslash before it: \. matches a period, \( a bracket, \$ a dollar sign. Inside square brackets most characters are literal anyway, so [.] also matches a period.

What is the difference between greedy and lazy?

A greedy quantifier such as .* takes as much text as it can, so <.*> on <b>hi</b> matches the whole string. Adding ? makes it lazy: <.*?> stops at the first > and matches <b>.

Why do I get empty matches?

A pattern that can match nothing — \d*, x? — succeeds between characters too. The tester marks empty matches with a thin red bar. Use + instead of * if you need at least one character.

Embed this calculator on your website

Free for any website or blog. Paste this code where you want the calculator to appear:

All free calculator widgets

Last updated: October 16, 2026

Menu

Categories

Finance Calculators30 calculatorsBusiness & Shopping Calculators9 calculatorsHealth & Fitness Calculators13 calculatorsMath & School Calculators23 calculatorsDate & Time Calculators19 calculatorsHoliday Countdowns17 calculatorsEveryday Tools47 calculatorsMic, Camera & Sound Tools10 calculatorsDeveloper Tools10 calculatorsImage & PDF Tools19 calculators

CalcWorthy

AboutContactPrivacy PolicyTerms of Use

Language

Language
EnglishEnglishالعربيةArabicবাংলাBanglaDeutschGermanEspañolSpanishفارسیPersianFrançaisFrenchעבריתHebrewहिन्दीHindiBahasa IndonesiaIndonesianItalianoItalian日本語Japanese한국어KoreanBahasa MelayuMalayNederlandsDutchPolskiPolishPortuguêsPortugueseРусскийRussianไทยThaiTürkçeTurkishУкраїнськаUkrainianاردوUrduTiếng ViệtVietnamese简体中文Simplified Chinese