Home
DT

Regex tester & quick cheat sheet

See matches, capture groups and replacements update as you type.

This tool runs entirely in your browser. Nothing you type is sent to a server.

Regular expressions pack a lot into one line, which is exactly why they are hard to verify by reading. Whether \d{3}-\d{4} catches everything you intended — and nothing you did not — only becomes clear when you run it against real data.

This tester highlights matches as you type, breaks out capture groups and named groups in a table, and previews replacement output before you commit to it. Common patterns for email, URL, IPv4, phone numbers and UUIDs are one click away, and a cheat sheet stays open below the workspace.

How to use

  1. Write the pattern and set flagsEnter the expression between the slashes and toggle flags: g finds every match, i ignores case, m makes ^ and $ match at line boundaries. Syntax errors are reported directly under the field.
  2. Provide realistic test inputInclude both strings that should match and strings that should not. Most regex bugs are not about missing matches — they are about matching too much.
  3. Verify with highlight and list viewsThe highlight view shows matched spans in context; the list view gives each match's index and captured groups. A group showing undefined means it was optional or sat in an untaken alternation branch.
  4. Preview the replacementIn the replace view, use $& for the whole match, $1 for the first capture group and $<name> for a named group, and see the result immediately.

Frequently asked questions

Will patterns built here work in Python or Java?

This tool uses the JavaScript (ECMAScript) engine, and the core syntax is shared across languages.

Details differ, though. JavaScript has no \A or \z absolute anchors — use ^ and $. \d matches ASCII digits only in JavaScript, while Python includes Unicode digits by default. Named groups use (?<name>...) in JavaScript, Python and Java alike, but Python's replacement reference is \g<name> rather than $<name>.

Only the first match shows up.

Check whether the g (global) flag is on.

Without g, exec and match return the first match and stop, and this tool follows the same rule. Note the mirror-image trap in code: calling test() repeatedly with a g regex keeps lastIndex between calls, so results alternate between true and false. For a simple existence check, leave g off.

My regex suddenly hangs on long input.

That is almost certainly catastrophic backtracking.

Nested quantifiers such as (a+)+b make the number of paths the engine must try grow exponentially with input length. In a running service this is the ReDoS denial-of-service class. Avoid nested quantifiers, narrow .* to something like [^"]*, and never interpolate untrusted user input into a pattern.

Concepts worth knowing

Greedy versus lazy quantifiers

*, + and {n,m} are greedy by default: they consume as much as possible, then give characters back only as needed. That is why <.*> applied to <b>bold</b> matches the entire string rather than just <b>.

Adding ? makes a quantifier lazy, consuming as little as possible, so <.*?> matches <b> and </b> separately. For HTML tags, quoted strings and bracketed log segments, knowing this one distinction resolves most problems.

Capturing, non-capturing and named groups

(...) stores what it matched. If you only need grouping, (?:...) avoids the storage — unnecessary captures clutter results and cost a little performance.

Once you have several groups, counting $1 and $2 becomes miserable. Naming them — (?<year>\d{4})-(?<month>\d{2}) — lets your code read match.groups.year and keeps working when you insert another group later.

Lookahead and lookbehind

(?=...) asserts that something follows without consuming it; (?!...) is its negation. (?<=...) and (?<!...) look backwards.

They shine when several conditions must hold at once. ^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$ expresses 'at least eight characters including a lowercase letter, an uppercase letter and a digit' in a single line, because each lookahead checks from the same position without consuming input.

Related tools

Last updated: 2026-08-12