Unit Testing a Regex Pattern

Pin a pattern down with a small regression suite of should-match and should-not-match cases, then share the whole suite as a single link a teammate can open and verify.

ZERO UPLOAD · ALL LOCAL
  1. Type a regular expression in the pattern field and toggle the g, i, m, s, and u flags you need. Matching runs automatically as you type.
  2. Paste your test text into the editor below. Every match highlights inline, and each capture group gets its own tint.
  3. Step through matches with the arrows above the inspector to see the full match and every capture group with its exact character range.
  4. Switch to Replace to preview substitutions live, using $1 or $<name> references in the replacement field.
  5. Switch to Unit Tests to pin the pattern down: add test strings, mark each as should match or should not match, and watch the pass count update.
  6. Click Share to copy a link that reproduces your pattern, flags, text, and test cases, or open Explain to read the pattern token by token.

Worked examples for this use case

Building a regression suite for a product SKU pattern

Before
Pattern: ^[A-Z]{2}\d{4}$
Test strings: AB1234, ab1234, AB12345
After
AB1234 is marked should match and passes. ab1234 and AB12345 are marked should not match and both correctly fail, so the summary line reads 3 of 3 passing.

Result

  

Unit Testing a Regex Pattern Before You Rely on It

A pattern that passes on the one string you tried it against is not tested; it is only unrefuted. The gap between those two states closes the moment you write down a handful of cases the pattern must handle correctly, positive and negative alike, and check them as a group instead of trusting a single example to represent every input your code will ever see.

Why one passing example is not the same as a tested pattern

Regular expressions fail in a specific, predictable way: they usually match more than the author intended, not less. A pattern like <[A-Za-z0-9]+> written to match HTML tags also matches something like <1>, which is not a valid tag at all, because a plus quantifier happily repeats past the point the author actually meant to stop.1 A pattern written and tested against exactly one happy-path string almost never gets caught matching too broadly, because the one string you tried never exercised the ambiguous edge the pattern actually leaves open.

Unit Tests mode exists to close that gap by treating a pattern the way you would treat a function: define a small set of inputs, decide what the correct output should be for each one, and run all of them together every time the implementation changes.2 A product SKU pattern like ^[A-Z]{2}\d{4}$ looks obviously correct at a glance, yet a test batch immediately reveals whether it correctly rejects a lowercase variant or an extra trailing digit, the exact kinds of malformed input real user entry actually produces.

Writing negative cases that earn their place in the suite

A negative test case, one explicitly marked should-not-match, is doing real work only when it targets something the pattern plausibly could get wrong, not an input so obviously invalid it was never in question. For the SKU pattern, ab1234 tests the case-sensitivity assumption directly, and AB12345 tests whether the digit count is actually being enforced rather than merely suggested by the pattern's shape.

Reading the pass count as you refine the pattern

Every edit to the pattern field re-runs the entire test batch in one pass, and the summary line above the rows reports a simple fraction: how many of your defined cases currently pass. That single number turns "I think I fixed it" into a checkable claim the moment you finish typing, rather than something you have to verify by re-reading each row individually.

Iterating without losing track of which case is failing

Each row keeps its own PASS or FAIL badge visible at all times, so tightening the pattern to fix one failing case while accidentally breaking a previously-passing one shows up immediately as a badge flipping color, not as a silent regression you discover later. That immediate feedback loop is what makes iterating on a tricky pattern here faster than iterating inside application code, where you would otherwise need to re-run a whole test file just to see the effect of one small change.

Once every row shows PASS, you have something stronger than a pattern that "seems to work": you have a pattern with a specific, written-down definition of correct behavior that it currently satisfies, case by case. That written definition is what makes the pattern maintainable months later, when whoever edits it next has a concrete list of behavior to preserve instead of a single vague memory of what it was originally supposed to do.

Sharing the whole suite instead of just the pattern

A pattern shared on its own loses the context that makes it trustworthy: what it was actually tested against, and what a correct result was supposed to look like for each case. Clicking Share encodes the pattern, its flags, the test text, and every row in your Unit Tests suite, expectation included, into a single link and copies that link to your clipboard. Writing the encoded state into the address bar this way updates only what the browser displays; it never triggers a page load or a check that anything at that address actually exists.3

What a teammate sees the moment they open the link

Sending that link to a teammate hands them not just your pattern but the evidence it works, already loaded and ready to inspect the moment they open it. They see the same pass count you saw, can add a case you missed, and can confirm your fix actually addressed the specific input that was failing before, all without re-typing a single test string from a description in a chat message.

Because the entire suite lives inside the link itself rather than on a server, opening it later still reproduces the exact same state, pattern, flags, test text, and every row's expectation, even if the pattern in your actual codebase has since moved on. That makes a shared link a durable snapshot of "here is what I verified," worth attaching directly to a pull request or a code review comment instead of describing the test cases in prose.

When to use this

Use this guide whenever you want to pin a pattern down with a small regression suite of should-match and should-not-match cases before relying on it in code.

Examples

Building a regression suite for a product SKU pattern

Before
Pattern: ^[A-Z]{2}\d{4}$
Test strings: AB1234, ab1234, AB12345
After
AB1234 is marked should match and passes. ab1234 and AB12345 are marked should not match and both correctly fail, so the summary line reads 3 of 3 passing.
Sources
  1. 1.

    Jan Goyvaerts, "Regex Tutorial: Repetition with Star and Plus," regular-expressions.info, accessed August 2026. https://www.regular-expressions.info/repeat.html

  2. 2.

    Martin Fowler, "Unit Test," martinfowler.com, May 2014. https://martinfowler.com/bliki/UnitTest.html

  3. 3.

    MDN Web Docs, "History: replaceState() method," developer.mozilla.org, accessed August 2026. https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState

FAQ