🍱 Lunchbox Hands

Regex Tester

Test regular expressions with highlighted matches

Enter a regex pattern and test string to see all matches highlighted in the text. View each match with its index and capture groups in a table below. Includes preset patterns for common matches like emails, URLs, phone numbers, and IP addresses. Patterns run in your browser's JavaScript regex engine, and nothing you type is sent anywhere.

What the tester does

Every time you edit the pattern, the flags or the test string, the tool builds a JavaScript RegExp from the first two and runs it over the third. With the g flag it loops through every match; without it, it reports only the first. The highlighted view marks each match in place, and the table lists them with their position. If the pattern or flags are invalid, the browser's error message appears instead, for example Unterminated group for (a or Invalid flags supplied to RegExp constructor 'gx' for a flag JavaScript does not have.

The flags are whatever your browser supports: g, i, m, s, u, y and d everywhere current, and the newer v (Unicode sets) in recent browsers. Lookbehind such as (?<=\$)\d+ and Unicode property escapes such as \p{L}+ with the u flag both work.

Worked example: pulling dates out of text

Pattern (\d{4})-(\d{2})-(\d{2}), flags g, test string Invoice 1042 issued 2026-10-23, due 2026-11-22. gives two rows:

#MatchIndexGroups
12026-10-23202026, 10, 23
22026-11-22362026, 11, 22

1042 is not matched because it is not followed by a hyphen and two digits. The index is a zero-based count of UTF-16 code units, the same number match.index gives you in code, so an emoji earlier in the string counts as 2.

What the presets match (and what they let through)

The five preset buttons fill the pattern box with deliberately simple patterns. They are a quick starting point for finding things in text, not validators:

  • Email finds ana@example.com and bob.smith+news@mail.co.uk, but not ops@localhost, because it requires a dot and a two-letter-or-longer ending after the @.
  • URL is https?:// followed by anything up to whitespace, so trailing punctuation such as a closing parenthesis or full stop is included.
  • Phone matches an optional +, then at least nine characters of digits, spaces, hyphens and parentheses that start and end with a digit. It does not check country formats.
  • IPv4 accepts any one to three digits per part, so 999.300.1.1 matches even though no octet can exceed 255.
  • Hex Color accepts 3 to 8 hex digits, which includes invalid CSS lengths such as #12345.

For stricter versions with explanations, browse the Regex Library, and for syntax reminders keep the regex cheat sheet open in another tab.

Limits worth knowing

  • It finds matches only. There is no replace or split mode, and no step-by-step debugger.
  • Zero-length matches are counted. x* against axxb gives four rows: an empty match at 0, xx at 1, then empty matches at 3 and 4. Empty matches appear in the table but have nothing to highlight.
  • There is no timeout. A pattern prone to catastrophic backtracking can hang the tab, which is also a good way to see why it would be a denial-of-service risk on a server. See catastrophic backtracking explained.
  • Patterns are entered without the /.../ delimiters. Typing /abc/i searches for the literal slashes and the letter i.

Frequently asked questions

Which regex flavor does this tester use?

JavaScript (ECMAScript). The pattern is compiled with new RegExp(pattern, flags) in your browser, so the results match what the same pattern does in browser JavaScript, Node.js, Deno or Bun. Python, PCRE (PHP), Java and .NET mostly agree on the basics but differ in the details, so a pattern that works here can still fail elsewhere, and the reverse.

Why do I only see one match?

The g (global) flag is missing. Without it, a JavaScript regex stops at the first match, and the tester shows exactly that. The Flags box starts with g filled in; if you cleared it or replaced it with other flags, add g back, for example gi.

Why is (?i) or a++ an error here when it works in Python or PHP?

JavaScript does not support inline flag prefixes like (?i), possessive quantifiers like a++ or atomic groups like (?>...). In JavaScript, use the Flags box for case-insensitivity (i), and rewrite possessive or atomic constructs, often with a lookahead and backreference. The error message shown under the test string is the browser's own, for example Invalid group or Nothing to repeat.

Are named capture groups supported?

Yes, (?<year>\d{4}) compiles and matches normally. The Groups column lists capture groups by position, separated by commas, and does not print the names. A group that did not take part in the match (an optional group that was skipped) shows as an empty entry.

Can a regex freeze the page?

Yes. The pattern runs on the page itself, again on every keystroke, with no timeout. A pattern with nested quantifiers such as (a+)+$ tested against a long string that almost matches can take exponential time and lock the tab. If the page stops responding, close the tab and shorten the test string or fix the pattern.

Get weekly dev tools and tips