Regex Tester & Explainer

Test regular expressions with live match highlighting. Match mode shows capture groups and allows navigation between matches. Substitution mode shows replacement results. List mode extracts all matches one per line. When nothing matches, the "Why didn't it match?" panel gives specific reasons.

regex-tester.tool
/
/
Match Results
Quick Patterns

Regex Is Easier Than It Looks

A regular expression is just a search pattern with a syntax that intimidates people at first glance. Once you know that \d means any digit, + means one or more, and () captures a group — most patterns become readable. Type your pattern above and the Plain-English Explanation panel breaks it down token by token as you type.

Three Modes

  • Match — highlights every occurrence in your test string. Match Details below shows each match with its position and any captured group values. Use the ▲▼ buttons to navigate between matches when there are many.
  • Substitution — shows what the text looks like after replacing all matches. Use $1, $2 to insert captured group values, or $& for the whole match.
  • List — extracts every match and outputs them one per line, nothing else. Useful when you want to pull a clean list of values from a document without the surrounding text.

Why Didn't It Match?

When your pattern finds no matches, the "Why didn't it match?" panel activates automatically. It checks for the most common silent failures: case mismatch (the pattern would match with the i flag), anchors that are too strict (^ and $ requiring the entire string to match), Windows line endings interfering with $, and unescaped dots that may not be doing what you think.

The Four Flags

g (global) — find every match, not just the first. Almost always want this on. i (case insensitive) — hello matches Hello, HELLO, hElLo. m (multiline) — makes ^ and $ match the start and end of each line, not just the whole string. s (dotAll) — makes . match newline characters too, useful when your pattern needs to span multiple lines.

Frequently Asked Questions

The most common cause is using .* (dot-star) which matches everything. Try a more specific character class — for example, to match content inside quotes use "[^"]+" rather than ".*?". The [^"] means any character except a double quote, so it stops at the first closing quote. Also check that you have not forgotten word boundaries — \bword\b matches the standalone word, not "password" or "wording".
.* is greedy — it matches as many characters as possible. .*? is lazy — it matches as few as possible. Given the string <b>bold</b> and <i>italic</i>, the pattern <.*> with greedy matching captures everything from the first < to the last >. With lazy matching <.*?> captures each tag individually. Add ? after any quantifier to make it lazy: *?, +?, {3,6}?.
List mode extracts all match values and outputs them one per line, with nothing else. It is useful when you have a large document and want to pull out a clean list — all email addresses, all dates, all phone numbers — without the surrounding text. Copy the output directly to a spreadsheet or another tool.
It activates automatically when your pattern finds zero matches and suggests specific reasons. It checks whether the pattern would match if the i (case insensitive) flag were enabled, whether removing ^ or $ anchors would produce a match, whether Windows line endings (CRLF) might be interfering, and whether an unescaped dot might not be behaving as intended. It is not a guaranteed diagnosis — just the most common silent failure modes.
Nigerian numbers start with 070, 080, 081, 090, or 091 followed by 8 digits. The pattern is: ^(\+234|0)[789][01]\d{8}$ — the ^ and $ anchors ensure the whole string is a phone number. The (\+234|0) matches either the international prefix or a leading zero. Enable the m flag if testing multiple numbers on separate lines. Load the "NG Phone" quick pattern in the tool to see it with sample numbers.
A regular group (...) captures the matched text as $1, $2 etc. A non-capturing group (?:...) groups tokens for alternation or quantifiers without capturing. Use it when you need the grouping logic but do not need the captured value — for example (?:https?|ftp):// matches both http:// and https:// without capturing the protocol as a group. This keeps your group numbering cleaner and is marginally faster.
A lookahead checks what comes after the current position without consuming characters. Positive lookahead (?=...) asserts that a pattern follows. Negative lookahead (?!...) asserts it does NOT follow. For example \d+(?= dollars) matches a number only if followed by " dollars", but the word "dollars" is not part of the match itself. Lookbehinds (?<=...) and (?<!...) work similarly but look at what came before.
JavaScript and Python use different regex engines. JavaScript does not support some Python/PCRE features: named groups use different syntax (Python uses (?P<name>...) while JavaScript uses (?<name>...)), lookbehinds are only supported in modern browsers, and some Unicode property escapes differ. If your pattern uses Python-specific syntax, it will need adjustment for JavaScript's RegExp engine.
Escape it with a backslash. In regex, . means any character — to match a literal dot, write \.. A bracket means start of character class — write \[ for a literal bracket. Characters that need escaping in regex: \ . * + ? ^ $ { } [ ] ( ) | — basically any character that has a special meaning in regex syntax.