Skip to content

Regex Tester

Type a JavaScript regular expression and some text: every match is highlighted as you type, with its position, its numbered and named groups, a replacement preview and a token-by-token explanation of the pattern. Matching runs in a background worker with a time limit, so a runaway pattern cannot freeze the page. Free, no sign-up.

The pattern without its surrounding slashes, in JavaScript syntax — the regex engine is your browser's own.

As a JavaScript literal: /\b(?<year>\d{4})-(?<month>0[1-9]|1[0-2])-(?<day>0[1-9]|[12]\d|3[01])\b/g
Flags

Checks months 01–12 and days 01–31, but not the length of each month: 2024-02-31 still matches.

$1 or $<name> inserts a group, $& the whole match, $$ a dollar sign.

Matches

2 matches

Submitted 2024-03-15, revised 2024-11-02; the 2024-13-01 typo is not a date.
#MatchPositionGroups
12024-03-1510–201: 20242: 033: 15year: 2024month: 03day: 15
22024-11-0230–401: 20242: 113: 02year: 2024month: 11day: 02

What the pattern says

  1. \bA word boundary
  2. (?<year>Start of capture group 1, named “year”
  3. \dA digit, 0–9
  4. {4}Exactly 4 times
  5. )End of the group
  6. -The text “-”
  7. (?<month>Start of capture group 2, named “month”
  8. 0The text “0”
  9. [1-9]One character from: 1–9
  10. |Or: the alternative on the right is tried next
  11. 1The text “1”
  12. [0-2]One character from: 0–2
  13. )End of the group
  14. -The text “-”
  15. (?<day>Start of capture group 3, named “day”
  16. 0The text “0”
  17. [1-9]One character from: 1–9
  18. |Or: the alternative on the right is tried next
  19. [12]One character from: 1 2
  20. \dA digit, 0–9
  21. |Or: the alternative on the right is tried next
  22. 3The text “3”
  23. [01]One character from: 0 1
  24. )End of the group
  25. \bA word boundary

How to Use the Regex Tester

  1. 1. Write the pattern. Leave out the slashes — \d{4}, not /\d{4}/. The line under the box shows it as a JavaScript literal, flags included, ready to copy into code.
  2. 2. Choose the flags. g finds every match instead of the first, i ignores case, m makes ^ and $ work line by line, s lets . cross line breaks, and u or v switch on full Unicode handling.
  3. 3. Paste the test text. Matches are highlighted in alternating colours so neighbours stay distinct, and the table lists each one's position and groups.
  4. 4. Preview a replacement. $1 or $<name> inserts a group and $& the whole match; the result updates with the matches.
  5. 5. Or start from the library. Dates, email addresses, web addresses, DOIs, ISBNs, US phone numbers, APA citations, doubled words and double spaces — each with a note on what it misses.

Regex Syntax at a Glance

PatternMatchesExample
.Any character except a line breakc.t finds cat, cot and c-t
\d \w \sA digit, a word character (letter, digit, underscore), whitespace\d\d finds 42
\D \W \SAnything except a digit, word character or whitespace\S+ finds a run of non-spaces
[abc] [a-z] [^0-9]One character from a set or range, or not in itgr[ae]y finds gray and grey
^ $The start and end of the text — of each line with m^# finds a # that starts a line
\bA word boundary\bcat\b finds cat but not concatenate
* + ?Zero or more, one or more, zero or onecolou?r finds color and colour
{3} {2,} {2,4}Exactly, at least, between\d{4} finds a four-digit year
+? *?The same, but as few as possible (lazy)<.+?> finds one HTML tag at a time
(…) (?<name>…)A capture group, numbered or named(?<year>\d{4})
(?:…)A group that does not capture(?:Mr|Ms)\. finds Mr. and Ms.
(?=…) (?!…) (?<=…) (?<!…)Lookahead and lookbehind: a check that consumes nothing\d+(?=%) finds the 50 in 50%
\1 \k<name>The same text a group already matched(\w)\1 finds the ll in hello

To match a special character itself, put a backslash before it: \. matches a full stop, \( a parenthesis, \$ a dollar sign. Inside square brackets most characters lose their special meaning, so [.] matches a full stop too.

A Worked Example

The tester opens with an ISO 8601 date pattern and the g flag:

Pattern

\b(?<year>\d{4})-(?<month>0[1-9]|1[0-2])-(?<day>0[1-9]|[12]\d|3[01])\b

Test text

Submitted 2024-03-15, revised 2024-11-02; the 2024-13-01 typo is not a date.

Matches

  • 2024-03-15, characters 10–20 — groups 1: 2024, 2: 03, 3: 15, also named year, month and day
  • 2024-11-02, characters 30–40

Replacement and result

$<day>/$<month>/$<year> gives: Submitted 15/03/2024, revised 02/11/2024; the 2024-13-01 typo is not a date.

The third date is skipped because the month group only accepts 01 to 12. Positions count characters from zero, the end being one past the last character matched — the numbers JavaScript's match.index reports. The pattern still accepts 2024-02-31: a regular expression can check the shape of a date, not the calendar.

Catastrophic Backtracking and the Time Limit

JavaScript's regex engine backtracks: when part of a pattern fails, it goes back and tries every other way the earlier parts could have matched. With nested quantifiers such as (a+)+$, the number of ways doubles with each extra character of a string that almost matches. Against thirty a's and an exclamation mark, that one test takes seconds in Chrome's engine; against forty, hours — and while it runs, an ordinary page is frozen.

Here, matching runs in a Web Worker — a separate thread created on this page — and is stopped after 1.5 seconds with a message saying why. The explanation also warns when a repeated group contains its own + or *. The fix is usually to remove the ambiguity: a+$ instead of (a+)+$, or a character class that cannot overlap with what follows it.

Frequently Asked Questions

Which regex flavour does this tester use?
JavaScript's (ECMAScript), run by your browser's own engine, so a pattern that works here works the same in JavaScript, TypeScript and Node.js. Other languages differ at the edges: Python writes named groups as (?P<name>…), and PCRE and recent Python versions add possessive quantifiers and atomic groups that JavaScript lacks.
Why does my regex only find the first match?
Without the g flag, a JavaScript regex stops at its first match. Tick g to find every one. The replacement preview follows the same rule: without g, only the first match is replaced.
Which characters need a backslash?
Outside square brackets, . * + ? ^ $ { } ( ) | [ ] and the backslash itself have special meanings, so match them literally by putting a backslash in front. With the u or v flag, escaping any other character is an error, which catches typos.
What do $1 and $<name> mean in the replacement?
They insert what a capture group matched: $1 the first group, $<year> the group named year. $& inserts the whole match, $` and $' the text before and after it, and $$ a literal dollar sign.
Can a regular expression validate an email address?
Only roughly. The full address syntax allows quoted names and other forms no practical pattern handles, so the library's email pattern catches everyday addresses and accepts a few invalid ones. The only real test of an address is sending it a message.
Why did my pattern time out?
Matching stops after 1.5 seconds to keep the page usable, and the cause is almost always catastrophic backtracking from nested quantifiers. Look for a repeated group whose content is itself repeated — (\w+)*, (a|aa)+ — and rewrite it so each character can be matched only one way.
Is my text sent anywhere?
No. Matching, replacing and the explanation all happen in your browser. The background worker is created on this page from the tester's own code, not downloaded, and your pattern and text never leave the page.

Related Tools

More in Data, Markup & Code

See all Data, Markup & Code