Regex Railroad Diagram Visualizer

Paste a regular expression and see it drawn as a railroad diagram, explained in plain English and parsed token by token, with its shortest and longest possible match.

Visualizer Web & Dev Updated Oct 3, 2026
Learn how this works
How to Use
  1. Type or paste a regular expression in the box (no surrounding slashes), and any flags in the small box after it.
  2. Follow the railroad diagram from the filled dot to the open one: boxes are things to match, branches are choices, a dashed loop underneath means repeat and a dashed arc on top means optional.
  3. Read the plain-English breakdown beside it, and the readouts for the number of groups and repeats and the shortest and longest text the pattern can match.
  4. Put a test string in to see what the pattern matches, highlighted. For each match’s index and groups, press Open in Regex Tester.
  5. Scroll to Show Work for the token-by-token parse, with each token’s position in the pattern. Download SVG saves the diagram.
Pattern
JavaScript · flags after the slash
/ /
optional
Open in Regex Tester →
Presets
Railroad diagram
Type a regular expression above to see its railroad diagram.

Plain-English breakdown

Test result

literal class / escape anchor repeat / optional
Capture groups
—
Repeats
—
Shortest match
—
Longest match
—

Worked Example

Read (\d{3})[-.\s]?(\d{4}).

The parser splits it into three items in a row:
1. (\d{3}) — capturing group #1 around \d (one digit 0–9) repeated exactly 3 times: 3 characters.
2. [-.\s]? — one character from “-”, “.” or whitespace, optional: 0 or 1 character. On the diagram it is a box with a dashed bypass arc over the top.
3. (\d{4}) — capturing group #2, exactly 4 digits: 4 characters.
Shortest match: 3 + 0 + 4 = 7 characters. Longest: 3 + 1 + 4 = 8 characters. Tested on “555-1234, 5551234, 555.1234 and 555--1234” it matches the first three; 555--1234 fails because the bypass allows one separator, not two.

The common mistake: forgetting that | splits the whole pattern. ^cat|dog$ is meant to accept a line that is exactly cat or dog, but alternation has the lowest precedence, so it reads as ^cat or dog$. The diagram makes this obvious: two branches, with the start anchor inside the top one and the end anchor inside the bottom one. With the gm flags on the lines cat, catapult, hotdog and dog it makes 4 matches (cat, the cat in catapult, the dog in hotdog, dog). ^(?:cat|dog)$ puts both anchors outside the branch and makes the intended 2.

Show Work

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

Reading the Diagram

Track
● → [a] → [b] → ○
Left to right, every box in order: ab
Branch
cat | dog | bird
The track splits; take exactly one branch, tried top first
Loop underneath
+  *  {2,5}
Repeat; the label says how often (1+, 0+, 2-5, ×3)
Arc over the top
?  *  {0,n}
Optional: the box can be skipped
Dashed box
( )  (?: )  (?<name> )  (?= )
A group: captured (#1, #2 …), not captured, named, or a look-around
Rounded box
^  $  \b  \B
An anchor: a position, so it adds 0 to the match length
Precedence
quantifier > sequence > |
ab+ repeats only b; ab|cd is (ab)|(cd)
Match length
min = Σ min   max = Σ max
Along the track; a branch takes its shortest and longest option, a repeat multiplies

Where Railroad Diagrams Come From

Syntax diagrams became famous with Kathleen Jensen and Niklaus Wirth’s Pascal User Manual and Report (1974), which drew the whole grammar of Pascal as tracks of boxes rather than as text rules. Programmers nicknamed them railroad diagrams because they look like a model railway’s points and sidings. They are still the standard picture of a grammar: json.org draws all of JSON this way, and SQLite’s documentation draws every SQL statement as one.

A regular expression is a grammar too, and a small one: just sequence, choice and repetition — exactly the three things a railroad shows, which is why Stephen Kleene’s 1950s regular expressions and Wirth’s diagrams fit so well together. Reading a regex correctly is mostly a matter of precedence. A quantifier binds to the single item before it, items in a row bind next, and | binds loosest of all — so ab+ repeats only the b, and ^cat|dog$ is two separate patterns. A diagram draws that precedence instead of leaving you to remember it.

About This Tool

This tool parses a JavaScript regular expression into a syntax tree and draws it as a railroad diagram in SVG. Alongside the picture it gives a plain-English breakdown, the number of capture groups and repeats, and the shortest and longest text the pattern can match — and Show Work lists the parse token by token, with each token’s position in the pattern, so you can see exactly how the string was read.

The test box highlights what the pattern matches, using your browser’s own RegExp engine in a background worker that is stopped after 2 seconds, so a catastrophic pattern cannot freeze the page. Everything runs in your browser; nothing you type is uploaded. To learn the language from the ground up, read Regular Expressions Explained.

It is the companion to the Regex Tester: this page shows how a pattern is built, the tester shows what it matches, with every match’s index and groups, replace and split.

Related tools: Regex Tester, JSON Formatter, and Cron Expression Builder.

Frequently Asked Questions

What is a railroad diagram?

A drawing of a grammar as train track. You start at the dot on the left and travel to the end; every box you pass must be matched, in order; where the track splits you take one branch; where it loops back you may go round again. Niklaus Wirth used them to define Pascal in 1974, json.org uses them for JSON, and they turn a pattern like (\d{3})[-.\s]?(\d{4}) into three boxes and one bypass you can follow with a finger.

Which regex flavour does it understand?

JavaScript (ECMAScript): literals, character classes, capturing, non-capturing and named groups, alternation, every quantifier including lazy ones, anchors, \d \w \s and the other escapes, \p{…} with the u flag, back-references and look-ahead and look-behind. Validity is checked by your browser’s own RegExp engine; if the pattern is invalid you get its error message and the diagram shows how the pattern reads so far.

What do the dashed loops and arcs mean?

A dashed line looping back underneath a box means it can repeat, and the label says how often: repeat 1+ for +, repeat 0+ for *, repeat ×3 for {3}, repeat 2-5 for {2,5}. A dashed arc over the top marked optional means the box can be skipped (? or *). A box with both, like [-.\s]?’s bypass, can be passed through once or not at all.

Why does ^cat|dog$ match “catapult”?

Because | has the lowest precedence of anything in a regex: it splits the whole pattern into ^cat OR dog$, not ^(cat|dog)$. The diagram shows it at once — the ^ sits inside the top branch only. With the gm flags on the four lines cat, catapult, hotdog and dog it makes 4 matches; ^(?:cat|dog)$ makes the intended 2.

How is this different from the Regex Tester?

The Regex Tester shows what a pattern matches: each match’s index, length and groups, a replace preview and what each flag changed. This page shows how the pattern is built: the diagram, the plain-English reading, the parse and the shortest and longest possible match. The Open in Regex Tester link carries your pattern, flags and test text across.

How do I use the Regex Railroad Diagram Visualizer?

Just type your numbers. The answer shows up right away — there is no button to press. Change anything and it updates by itself.

Do I need to install or sign up for anything?

Not at all — it runs in the browser with nothing to install and no account. After it loads once, it even works without an internet connection.

Is my information private?

Yes. Everything happens in your browser. Nothing you type is sent to a server or saved anywhere.

Common Use Cases

Understand a regex you inherited

Paste a 60-character validation pattern from a codebase and read it as a diagram and a numbered breakdown instead of a wall of symbols.

Find an alternation bug

See that ^cat|dog$ anchors only one branch, then wrap it as ^(?:cat|dog)$ and watch the ^ and $ move outside the split.

Check length limits

The readouts give the shortest and longest match: #([0-9a-fA-F]{6}|[0-9a-fA-F]{3}) is 4 or 7 characters, so a 9-character field limit is safe.

Explain a regex to a teammate

Download the diagram as SVG for a pull request or a wiki page, with the plain-English breakdown pasted underneath.

Learn regular expressions

Add a +, a group or a | one at a time and watch the diagram change — the quickest way to see how quantifiers bind to the single item before them.

Last updated: