Regex Visualizer
See the shape of a regular expression: branches, loops and groups drawn as a railroad diagram you can download as SVG — entirely on this device.
Type or paste a regular expression — no slashes, no flags.
Wide diagrams scroll inside this box — the page itself never scrolls sideways.
The outline lists every box in the diagram, in reading order.
Select a line to mark the characters it was drawn from.
JavaScript regular expressions only. PCRE, Python, Go and .NET syntax differ and are not drawn here.
The diagram is drawn by this page from its own parser — no diagram library, no server, nothing uploaded.
A diagram is a reading aid, not a proof: it shows what your pattern says, not whether it is correct or fast.
Anything this layout cannot draw faithfully appears as a plain labelled box, counted below — never as a wrong picture.
Box widths come from a committed monospace advance table, not from your fonts, so the SVG you download is identical everywhere; every label also carries textLength, so a font that measures differently stretches the text instead of clipping it.
This page never runs your pattern, so it cannot tell you whether it is slow on hostile input. Regex Tester
Test this pattern against text in the Regex Tester
Press ? for shortcuts
Do it offline:$
How to use it
- Paste the pattern itself, without the surrounding slashes and without the trailing flag letters — those belong in the flag row underneath, where a tick redraws the picture.
- Tick the flags you ship with. They are part of the picture: u turns \p{Script=Han} into a property box, s widens the dot box, m re-points the anchors.
- Read left to right. Each branch forks the rail, each repeat loops back over the boxes it covers, and every group draws a labelled frame around what it holds.
- Take it away: download the SVG, copy it, or switch to the outline — the same tree as indented text, which is also what a screen reader is given.
A long pattern is hard to argue about in a review because its shape is hidden in punctuation. Paste one here and the branches, repeats and group frames are drawn as a railroad diagram, with a matching text outline beside it. The drawing happens in this tab, and the picture downloads as SVG for a pull request or a design document.
Examples
/^(?:foo|ba[rz]){1,3}\d+$/gisequence n0 [0,24)
anchor n1 [0,1) ^
loop n2 [1,20) {1,3}
group n3 [1,15)
choice n4 [4,14) 2
terminal n5 [4,7) foo
sequence n6 [8,14)
terminal n7 [8,10) ba
class n8 [10,14) [rz]
loop n9 [20,23) +
class n10 [20,22) \d
anchor n11 [23,24) $The everyday shape: a fork with two ways through, wrapped in a loop that may run up to three times, then a second loop over the digit box. Every row carries the half-open offset span it came from, so a box and its characters can be pointed at together. Drawn: 12 boxes, 0 capture groups, no notes.
/(?<year>\d{4})-(?<month>\d{2})(?=\D)/sequence n0 [0,36)
named n1 [0,14) 1 year
loop n2 [8,13) {4}
class n3 [8,10) \d
terminal n4 [14,15) -
named n5 [15,30) 2 month
loop n6 [24,29) {2}
class n7 [24,26) \d
lookaround n8 [30,36) (?=
class n9 [33,35) \DNamed groups keep both facts a caller needs — the number and the name — on one frame, in source order. The lookahead sits off the main rail because it is a condition checked at that point, not characters the match consumes. Drawn: 10 boxes, 2 capture groups, no notes.
/((((((((((((((((((((((((((((((((\p{Script=Han}+?))))))))))))))))))))))))))))))))/usequence n0 [0,80)
capture n1 [0,80) 1
capture n2 [1,79) 2
capture n3 [2,78) 3
capture n4 [3,77) 4
capture n5 [4,76) 5
capture n6 [5,75) 6
capture n7 [6,74) 7
capture n8 [7,73) 8
capture n9 [8,72) 9
capture n10 [9,71) 10
capture n11 [10,70) 11
capture n12 [11,69) 12
capture n13 [12,68) 13
capture n14 [13,67) 14
capture n15 [14,66) 15
capture n16 [15,65) 16
capture n17 [16,64) 17
capture n18 [17,63) 18
capture n19 [18,62) 19
capture n20 [19,61) 20
capture n21 [20,60) 21
capture n22 [21,59) 22
capture n23 [22,58) 23
capture n24 [23,57) 24
capture n25 [24,56) 25
capture n26 [25,55) 26
capture n27 [26,54) 27
capture n28 [27,53) 28
capture n29 [28,52) 29
capture n30 [29,51) 30
capture n31 [30,50) 31
capture n32 [31,49) 32
opaque n33 [32,48) \p{Script=Han}+?A deliberate stress vector: 32 capturing groups around a lazy unbounded repeat of a script property. Past 32 levels the layout stops expanding and emits one plain labelled box carrying the source text it stands for, plus a counted note. Drawn: 34 boxes, 32 capture groups, 1 note: N_RAILROAD_OPAQUE.
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
The flag row is part of the picture
Flags change which boxes exist and what they cover. Without u or v a property escape is not a property at all, so it is drawn as the literal characters it really matches, with the parser's note attached. Tick s and the dot box stops excluding line terminators; tick m and the anchors move from the ends of the input to the ends of a line.
Anything unrepresentable is boxed and counted
Three things get a plain box instead of an expansion: constructs nested deeper than the layout cap, v-flag set operations on a browser whose engine lacks that flag, and inline modifier groups. Each raises a counted note. Twenty distinct notes are listed and a sentinel says how many more were held back.
Long labels shorten in the picture, never in the outline
A label longer than 64 characters is cut with an ellipsis so the geometry stays readable, and the full text is kept in the outline. Control characters, U+2028 and U+2029, and unpaired surrogates are shown in JavaScript escape notation: an invisible character in a box is worse than none.
Common errors
Position 1: this '[' opens a character class that is never closed — JavaScript refuses the whole pattern; add the matching ']', or write it as \[ to match a literal bracket.- There is no half-valid pattern and therefore no half-drawn picture: a refusal leaves the previous diagram on screen untouched, with the message and its caret frame beside the input. The parser producing this text is the one the drawing is built from, so the two cannot disagree.
this pattern needs more diagram boxes than the limit of 2000; nothing was drawn- The layout has a hard ceiling of two thousand boxes and prints the number. Past that point a picture stops being a reading aid anyway; the outline carries the same structure as text, and a smaller extract usually answers the question you had.
This pattern is 4097 characters and the reader stops at 4096. Nothing was parsed; shorten the pattern, or download the state file and split it.- The character bound belongs to the shared parser, so it is printed rather than implied. Nothing is parsed past a refusal — no partial tree, no partial drawing — and the state file hands the input back so it can be split without retyping.
FAQ
What exactly is in the SVG file this page downloads?
One self-contained document: rails and boxes as paths and rectangles, your labels as text, and a small fixed stylesheet the page owns. There is no script, no embedded image and no outside address referenced, so it renders identically wherever it is opened. Every text run carries an explicit advance width, so a viewer with different fonts cannot overflow the boxes.
Does the diagram show whether my pattern is slow or risky?
No. Drawing a pattern says what it describes, not what it costs: catastrophic backtracking depends on the input as much as the pattern, and measuring it against real text is the regex tester's job. Nothing here is compiled or executed, which is also why no pattern typed into this page can wedge the tab.
Which regex dialect is being drawn?
JavaScript, as specified in ECMA-262 — including named groups, lookbehind, property escapes and v-mode set notation. Patterns written for PCRE, Python, Go or .NET often parse anyway and then mean something else, so where the reading differs the parser attaches a note rather than guessing at intent.
Keyboard shortcuts
- ⌘/Ctrl + Enter
- Redraw the diagram now, skipping the debounce.
- ⌘/Ctrl + S
- Download the diagram as an .svg file.
- ⌘/Ctrl + C
- Copy the SVG markup while nothing is selected.
- ⌘/Ctrl + Shift + C
- Copy the SVG markup over an active selection.
- t
- Switch to the next theme.
- ? or ⌘/Ctrl + /
- Open the keyboard-shortcut reference.
- Esc
- Close the topmost overlay and return focus.