Skip to content
Julien Danjou Julien Danjou
May 13, 2026 · 6 min read

regex101: A Practical Guide to the Regex Tester Engineers Actually Use

regex101 is the online regex tester most engineers reach for. Live matching, explained groups, multi-flavor support, and a permalink for every pattern. Full guide to the features that matter and a short cheat sheet.

regex101.com is the regex tester most engineers open without thinking about it. Type a pattern, type a sample string, see what matches in real time, get a plain-English explanation of each group, copy a permalink for the colleague who needs to know what the pattern is doing. It is the kind of tool that quietly replaces a whole category of standalone apps.

This is a short guide to what is actually useful in it.

Why a regex tester is worth using at all

Regex is one of the few skills where reading is harder than writing. Anyone can chain [a-z]+@[a-z]+\.[a-z]+ together. Six months later, the same person opens the file and has no idea what it does. regex101 collapses the gap between “I wrote this” and “I understand this.” Every group is highlighted, every quantifier is annotated, every backreference is named.

The other thing regex101 is good at: it tells you when your pattern is wrong in a way the language runtime will not. Most regex engines fail silently. A misplaced backslash matches nothing instead of throwing. regex101 highlights the problem in the input itself, which is faster than the print-statement loop most engineers fall back to.

The features that matter

Multi-flavor support

Regex flavors differ in ways that bite. JavaScript does not support lookbehind in older engines. PCRE supports it everywhere. Python has its own escape rules. Go’s RE2 deliberately rejects backreferences. regex101 lets you pick the flavor (PCRE2, JavaScript, Python, Go, Java, .NET, Rust) and runs your pattern against the engine you actually target.

When debugging a pattern that “works locally but not in production,” the first thing to check is whether you tested it in the right flavor.

Live matches and explanation

Every match is highlighted in the input. Every group, lookahead, character class, and quantifier in the pattern is annotated in the “Explanation” panel on the right. This is the feature that turns regex101 from a tester into a teaching tool. Hand a colleague a permalink and they can read the pattern in English, not in regex syntax.

Every pattern, sample input, and flavor combination gets a unique URL. Save it, paste it in a PR, link it in a code comment that explains why the regex is the way it is. Permalinks survive across browsers, devices, and years.

The pattern with this:

^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$

against a sample input like 2026-05-13 produces a regex101 permalink that anyone can open and see the named groups (year, month, day) light up. That is the kind of breadcrumb you want to leave next to a regex in your codebase.

Code generators

Once a pattern works, the “Code Generator” tab produces a ready-to-paste snippet for most major languages. The snippet handles the escape rules (which is where most regex translation goes wrong), the flag setup, and the match-iteration boilerplate.

A common mistake is to copy the regex string out of regex101 without copying the flags. The generator includes the flags by default, which is one less thing to forget.

Substitution preview

The “Substitution” tab is the regex-replace counterpart of the match feature. Paste the replacement pattern, see the output in real time, confirm that your $1/\1 references point where you think they do. For one-off mass-edit jobs in a codebase (a sed script, a git filter-branch rename, a database column migration), this is where to test it before running it for real.

A short cheat sheet

The flavor flags that change the most behavior:

FlagEffect
gMatch all occurrences, not just the first.
iCase-insensitive.
m^ and $ match line starts and ends, not just input start/end.
s. matches newline characters.
xAllow whitespace and comments in the pattern (extended mode).
uUnicode mode (Java, JS, Python).

The constructs that most often get used wrong:

  • Lookahead (?=foo) and lookbehind (?<=foo). Zero-width, so they assert a condition without consuming characters. Older JavaScript engines do not support lookbehind.
  • Non-capturing groups (?:foo). Group for the regex engine’s purposes, but do not allocate a capture index. Use these by default; reserve capturing groups for the values you actually need.
  • Named groups (?<name>foo). Better than positional groups for anything you are going to reference later in code. PCRE, Python, .NET, and modern JavaScript all support them; older engines do not.
  • Anchors ^ and $. Without the m flag, they match only the start and end of the entire input, not each line.

When to reach for it

regex101 belongs in three workflows:

  1. Writing a new pattern. Faster than the language REPL because matches are highlighted in the input and the explanation panel keeps you honest about what each part of the pattern is doing.
  2. Reading an existing pattern. Paste it in, paste a sample input, read the explanation. Faster than puzzling it out from the syntax alone.
  3. Translating a pattern across engines. Switch flavors, see what breaks, use the code generator to get the right escape rules for the target language.

If you find yourself reaching for a print-statement debugger to figure out why a regex is not matching, you are paying time for what regex101 gives for free.

What regex101 is not

It is a pattern tester, not a regex generator. It will not write a regex for you from a description; you still have to know what you want to match. It is also not a benchmark: the matcher is fast, but the timing it reports is the JavaScript engine’s, not your runtime’s. For performance work, profile in the language you actually ship.

For everything else (write, read, debug, share, translate), it is the tool to keep open in a tab.

Stay ahead in CI/CD

Blog posts, release news, and automation tips straight in your inbox.

Recommended posts

Testing

Playwright route handlers fire only on requests they were registered before

May 13, 2026 · 5 min read

Playwright route handlers fire only on requests they were registered before

Why a `page.route()` call placed after `page.goto()` silently misses the request you wanted to intercept, and the registration-order rule that makes network mocks deterministic.

Rémy Duthu Rémy Duthu
Testing

vi.mock hoists. Your closure variables do not.

May 11, 2026 · 5 min read

vi.mock hoists. Your closure variables do not.

Why a Vitest mock factory that references a stub object returns undefined, the vi.hoisted() escape hatch, and the import-order rule that keeps your mocks predictable.

Rémy Duthu Rémy Duthu
Testing

pytest-xdist makes the suite faster and the flakes weirder

May 9, 2026 · 6 min read

pytest-xdist makes the suite faster and the flakes weirder

Why a test that always passes alone fails on `pytest -n auto`, the fixture-scope rule that prevents most worker races, and the worker_id pattern for genuinely shared resources.

Rémy Duthu Rémy Duthu