Regex Tester

Test and debug regular expressions with live match highlighting, group capture and a built-in cheatsheet.

MatchGroupsFlagsCheatsheet
3 matches
//g
Test String
146 chars · 3 lines

Matches (3)

Click a match to see capture groups
1hello@formatcraft.com
index 14len 21
2support@example.org
index 39len 19
3user.name+tag@company.co.uk
index 119len 27

All matching runs locally in your browser — your patterns and data stay private.

A regular expression is a pattern that describes a set of strings. Developers use them to validate input, search logs and pull values out of text. This tool runs your pattern against a test string with the browser's JavaScript regex engine, highlights every match in place and lists each one with its index, length and capture groups.

Matching is always global: the g flag is applied even when its toggle is off, so you see every match, not just the first. Keep that in mind when you move a pattern into code, because match() or exec() without g returns only the first match. The i, m and s toggles behave exactly as they do in JavaScript.

Results match what String.prototype.matchAll returns in modern browsers and Node.js. Other flavours such as PCRE, Python or Java differ in places, for example possessive quantifiers and inline (?i) flags. If you need to know what each part of a pattern means rather than what it matches, paste it into the Regex Explainer.

  1. Type the pattern into the pattern field without the surrounding slashes, for example \d+ rather than /\d+/.
  2. Paste the text you want to search into the Test String panel.
  3. Switch on i (ignore case), m (multiline) or s (dot all) if you need them. Global matching is always on.
  4. Check the highlighted text and the match list below it. Click a match that has capture groups to see each group's value.
  5. Open Reference for a quick token cheatsheet, and use the copy button next to the pattern to copy it as /pattern/flags.

  • Live, colour-coded highlighting of every match in the test string
  • Match list with the index and length of each match, plus a copy button per match
  • Numbered and named capture groups shown for each match
  • Toggles for the i, m and s flags; g is always applied
  • Match counter and the engine's own error message for invalid patterns
  • Built-in quick reference for character classes, anchors, quantifiers, groups and escapes

Extracting every number

Pattern: \d+
Text:    Order #1042 shipped 3 items on 2024-05-09
Matches: 1042, 3, 2024, 05, 09

Five matches. The date splits into three because - is not a digit.

Named capture groups

Pattern: (?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})
Text:    Released 2024-05-09 and 2025-01-31
Match 1: 2024-05-09  year=2024 month=05 day=09
Match 2: 2025-01-31  year=2025 month=01 day=31

Click a match in the list to see its group values by name.

Greedy vs lazy quantifiers

Text:  <b>bold</b> and <i>it</i>
<.+>   1 match:  <b>bold</b> and <i>it</i>
<.+?>  4 matches: <b>, </b>, <i>, </i>

.+ grabs as much as it can before backtracking to the last >. Adding ? makes it stop at the first >.

Anchors and the m flag

Pattern: ^\d{3}-\d{4}$
Text:    555-1234
         555-9876
Without m: 0 matches
With m:    2 matches

Without m, ^ and $ refer to the whole string, so a pattern meant for one line fails on multi-line input.

Invalid regular expression: /(/g: Unterminated group

An opening parenthesis has no matching closing one. Often you meant a literal ( character.

Close the group, or escape the parenthesis as \( to match it literally.

Invalid regular expression: /*.txt/g: Nothing to repeat

A quantifier (*, + or ?) appears with nothing before it. This usually happens when a shell glob like *.txt is pasted as a regex.

Write the regex equivalent, for example .*\.txt$, or escape the symbol as \* to match it literally.

Invalid regular expression: /[a-z/g: Unterminated character class

A [ opens a character class that is never closed.

Add the closing ], or escape the bracket as \[ if you meant a literal one.

A pattern copied from code matches nothing

It was copied from a string literal with doubled backslashes ("\\d+"), or with its delimiters and flags (/abc/i). Both are then treated as literal characters.

Remove one backslash from each pair, strip the surrounding slashes, and set flags with the toggles instead.

Why does the tester find every match even with g switched off?

The tester uses matchAll internally, which requires the g flag, so it always adds it. The flag toggles still decide what the copied /pattern/flags contains, which is what matters for your code.

Which regex flavour does it use?

JavaScript (ECMAScript), as implemented by your browser. Lookahead, lookbehind, named groups and \d, \w, \s all work. Syntax from other engines, such as possessive quantifiers (a++) or a leading (?i), is rejected with an error.

Do I need to double the backslashes?

Not here. The field takes the pattern exactly as you would write it between slashes, so type \d+. Backslashes only need doubling when the pattern goes inside a string, such as new RegExp("\\d+") or a JSON config file; the JSON escape tool can do that step for JSON.

Why do I see matches that are empty strings?

Your pattern can match zero characters. \d* matches an empty string at every position with no digit, so it produces matches between characters. Use + instead of * when at least one character is required.

What does undefined mean next to a capture group?

That group did not take part in the match, typically because it was optional (followed by ?) or on the side of an alternation that was not used.

How is this different from the Regex Explainer?

The tester runs a pattern against real text and shows what it matches. The Regex Explainer does not run the pattern; it breaks it into tokens and describes each one. Use the explainer to understand a pattern and the tester to confirm it behaves.