Layerbit

Regex Tester & Debugger

Live matching, a plain-English explanation of every token, a railroad diagram, a catastrophic-backtracking check, saved unit tests, code for ten languages, and a pattern generator that learns from your examples — all in your browser.

Expression Editor
JavaScript / ECMAScript
/
/
Invalid regular expression
Test String 0 Matches
Paste your test data here to see match highlights...
Ctrl+Enter re-runs · the privacy pill above counts network requests: it stays at zero
Matches and capture groups
Replacement Preview
What each part of the pattern does

Type a pattern above to see it explained token by token.

Railroad diagram

The diagram shows every path a string can take through the pattern: follow a line from the left circle to the right circle.

Catastrophic backtracking check

Static analysis of the pattern structure: nested unbounded repeats, overlapping alternatives under a repeat, and adjacent repeats that accept the same characters — the three shapes behind nearly every regex denial-of-service.

Unit tests

Tests live in the share link, so a reviewer gets the pattern and its expectations together. "Whole string" requires the match to cover the entire input; a group check compares a numbered or named group with an expected value.

InputExpectGroupValueResult
Code generator

          
Test against a whole file

Drop a log, CSV or any text file here. Each line is tested separately; you get the count of matching lines, the first matches, and a download of only the lines that matched. Files up to about 50 MB are fine.

Generate a pattern from examples

Paste strings that should match and strings that should not, one per line. The generator finds the shape the positive examples share (runs of digits, letters, separators), keeps literal parts they all have in common, and ranks candidates by how many examples each gets right. It is rule-based and runs locally; it is good at identifiers, codes, dates and keys, less good at free text.

Quick reference (JavaScript flavour)
Characters
.any char except newline (s: any)
\d \w \sdigit · word char · whitespace
\D \W \Stheir negations
[abc] [^abc]one of · none of
[a-z0-9]ranges
\p{L} \p{Script=Han}Unicode property (needs u)
\t \n \r \xHH \uHHHH \u{H…}escapes
Quantifiers
* + ?0+ · 1+ · 0 or 1
{n} {n,} {n,m}exact · at least · range
*? +? ?? {n,m}?lazy versions
Groups & references
(…)capture group
(?:…)non-capturing
(?<name>…)named group
\1 \k<name>backreference
a|balternation
(?i:…) (?-i:…)inline modifiers (ES2025)
Anchors & lookaround
^ $start · end (line with m)
\b \Bword boundary · not
(?=…) (?!…)lookahead · negative
(?<=…) (?<!…)lookbehind · negative
Replacement
$1 $<name>group
$&whole match
$` $'text before · after
$$literal $
Flags
gall matches
iignore case
mmultiline anchors
sdot matches newline
uUnicode mode
ysticky
dgroup indices
vset notation (ES2024)

A debugger, not just a tester

A regex tester tells you whether a pattern matches. A debugger tells you why, what it will do on the inputs you have not tried yet, and how to carry it into the language it will actually run in. The tabs above are that difference.

Explain and diagram

The pattern is parsed into a tree and every token described in plain English — what a character class contains, how greedy a quantifier is, which group number a capture gets. The railroad diagram draws the same tree as paths, which is the fastest way to spot an alternation that swallows more than intended.

Safety analysis

Nested unbounded repeats like (a+)+, overlapping alternatives under a repeat like (\w|\d)*, and adjacent repeats that accept the same characters are flagged with the exact fragment and a rewrite. The growth test then measures engine time as the input doubles, which is the empirical confirmation.

Tests that travel

Unit tests — should match, should not, whole-string, group equals — live in the share link alongside the pattern, so the person reviewing your change can run them, and the person editing the pattern next year can see what it was meant to accept.

Code for ten languages

Flags become re.IGNORECASE, RegexOptions.Multiline or (?im); named groups become (?P<name>) where needed; and anything the target engine cannot do — lookbehind in Go, backreferences in Rust — is called out before you paste it.

Whole-file batch runs

Drop a log or export and test every line. You get the number of lines that matched, the first few with their captures, and a download of only the matching lines — the quick filter you would otherwise write a script for.

Patterns from examples

Give it a handful of strings that should match and a few that should not; it infers the shared shape, keeps literal parts in common, and ranks candidates by the examples they get right. A starting point you then refine with the tests tab.

Quick Testing Templates

Click a template to load a pattern and test string. The last one is deliberately dangerous: open the Safety tab after loading it.

Test the failing case, not just the passing one

Most regex bugs are not "the pattern does not match" — they are "the pattern matches slightly more than intended", or "the pattern takes four minutes on one particular input". Both are invisible if you only ever test with an example that works.

The second category is worth taking seriously. Backtracking engines — JavaScript, Python's re, Java, .NET, PCRE — can take exponential time when a pattern is ambiguous, meaning there is more than one way to divide the same input between its parts. A pattern like ^(a+)+$ tested against thirty as followed by one X takes roughly a second; at forty characters it is about fifteen minutes. Our guide on catastrophic backtracking explains the mechanism and the fixes; the Safety tab applies those rules to your pattern automatically.

Nested quantifiers

(a+)+, (\d+)*, ([a-z]+)*. A quantifier immediately outside a group whose contents also repeat is exponential. It usually has a trivially equivalent safe form — (a+)+ matches exactly what a+ matches.

Ambiguous alternation

(\w|\d)* is dangerous because \d is contained within \w, so every digit can match two ways. Make alternation branches mutually exclusive, or collapse them: \w*.

Optional separators in a repeat

(\w+\s?)+$ appears in countless "validate a full name" patterns and is polynomial. Make the separator mandatory between tokens instead: ^\w+(\s\w+)*$.

Flags change the answer, not just the search

Three flags cause most of the confusion when a pattern behaves differently than expected:

Capture groups are the other common source of surprise: (...) captures and is numbered left to right by opening parenthesis, (?:...) groups without capturing, and (?<name>...) captures by name. Adding a group in the middle of a pattern renumbers everything after it, which quietly breaks any code indexing matches positionally. Named groups avoid that entirely — and the Explain tab shows you every group's number at a glance.

The replacement preview

Substitutions have their own hazards. $1 inserts the first capture group, $& the whole match, and $$ a literal dollar sign — so a replacement containing a currency amount needs escaping. Previewing the result against real input is faster than reasoning about it, especially when the replacement references groups whose numbering you have just changed.

One pattern, several engines

Regular expressions are not one language. JavaScript, PCRE (PHP, grep -P), Python, Java, .NET, Go's RE2 and Rust's regex crate agree on the core — classes, quantifiers, groups, anchors — and disagree at the edges. Go and Rust guarantee linear time by refusing lookaround and backreferences entirely. Python spells named groups (?P<name>…). Ruby's ^ is always a line anchor. POSIX sed has no \d. The Code tab translates what it can and names what it cannot, which is the part that otherwise costs an afternoon.

Local, which matters for this tool

The text people test patterns against is usually the real thing: production logs, customer exports, source code. All matching here is done by the JavaScript engine in your browser tab; nothing is posted anywhere. The files you drop in the batch tab are read with the browser's FileReader and never leave your machine.

Technical FAQ

The native JavaScript (ECMAScript) engine in your browser, which covers lookbehind, named groups, Unicode property escapes and the v flag in current Chrome, Firefox and Safari. The Code tab converts flags and syntax for Python, Go, Java, C#, PHP, Ruby, Rust and the shell tools, and lists any feature the target engine lacks, so a pattern that works here is carried over correctly or you learn why it cannot be.

The pattern is parsed into a tree and scanned for three shapes: an unbounded repeat containing another unbounded repeat, alternatives under a repeat whose first characters overlap, and two adjacent repeats that can accept the same characters. Each finding shows the fragment and a safer rewrite. The growth measurement then runs the pattern on your test string at one, two, four and eight times its length and reports how the time grows: roughly doubling is linear and fine, quadrupling or worse means the ambiguity is real.

A transparent textarea captures your keystrokes while a perfectly aligned layer behind it renders the colourised matches and mirrors the scroll position. Alternate matches use two shades so adjacent matches stay distinguishable, and the match list below shows every capture group with its index range.

The same replacement patterns JavaScript's native String.replace() understands: $1, $2 and so on for numbered capture groups, $<name> for named groups, $& for the whole match, $` and $' for the text before and after it, and $$ for a literal dollar sign. It respects whichever flags are active, so without the g flag only the first match is replaced, the same as the highlighting above it.

In the page, and in the share link when you copy one: the pattern, flags, test string and the full test table are compressed into the URL fragment, which browsers never send to a server. Paste the link into a code review or a ticket and the reader gets the pattern with its expectations and can run them. Nothing is stored on Layerbit's side; the optional history lives in your browser's own storage.

It is a rule-based synthesiser, not a language model. It splits each positive example into runs of digits, letters, whitespace and punctuation, checks whether all examples share the same sequence, and builds patterns from that shape with exact, loose and unanchored variants, then scores each candidate against your negative examples. For structured strings such as invoice numbers, SKUs, dates, keys and identifiers it produces a usable pattern immediately; for free text it gives you a starting point to edit.

If you are testing patterns against proprietary application logs or databases containing personal information, pasting that text into a server-side tool is a data transfer you may not be allowed to make. Everything here, including the batch file mode, runs in your browser, and the header indicator counts the network requests the page makes so you can see that it stays at zero.

Deployment Changelog