Set algebra
for regex.

A regex engine answers one question: does this string match? RegexSolver answers questions about the patterns themselves: whether two rules overlap, whether a validator accepts more than it should, what one pattern matches that another doesn't.

10,000 req/month · full access · no payment details needed

A= /api/v[12]/.*B= .*/users/[0-9]+
A Bthe strings both patterns accept, as one new pattern
PATTERN

Reason about patterns, not test cases.

A matcher consumes a string and a pattern and hands back a boolean. RegexSolver consumes patterns alone and reasons about the sets they describe:

  • Does pattern A match strictly fewer strings than B?
  • What strings do two firewall rules have in common?
  • Does removing rule C create a security gap?
  • How many valid inputs does this validator accept?
FIG. 1
What each machine consumes, and what it returns
MATCHER
"user@example.com"+/.+@.+\..+/true
REGEXSOLVER
/email_v1/ /email_v2/true
| /[a-z]+/ |
/A/ /B//new_pattern/

Where patterns are logic.

Security & WAF

Intersect two firewall rules to see exactly what they both allow. Take the difference to find strings one rule blocks and the other lets through. Shadow rules and coverage gaps surface as patterns, before they reach production.

difference(rule_a, rule_b) → gap

Business rule engines

Prove that two validation rules are truly equivalent, or that a new rule is a strict subset of the old one. Conflicts between conditions are caught structurally instead of surfacing as silent data corruption.

subset(new_rule, old_rule) → true

QA & test data

Generate deterministic, valid strings from any pattern, including edge cases at exact length boundaries. Paginate through the language without duplicates — the same offset always yields the same strings.

strings(pattern, limit, offset) → ["abc01", "abc02", …]

API & schema validation

Check that a validator is neither too strict (empty: nothing passes) nor too permissive (total: everything passes). Complement gives you the exact set of strings it rejects.

complement(validator) → rejected

Inspect patterns. Compute new ones.

Full API reference →
OperationNotationAnswersReturns
ANALYZE — inspect a pattern's language
cardinality|A|How many distinct strings does the pattern match?count | ∞
lengthlen(A)Shortest and longest possible match.[min, max]
empty / totalA = ∅ · A = Σ*Matches nothing at all? Matches everything?boolean
equivalentABSame language, regardless of syntax?boolean
subsetABIs every match of A also a match of B?boolean
patternre(A)A compact, human-readable regex for any term.regex
COMPUTE — derive new patterns
intersectionABStrings matching all of the patterns.term
unionABStrings matching any of the patterns.term
differenceABStrings in A but not in B.term
complementAEvery string the pattern does not match.term
concatenationA · BPatterns joined in sequence.term
repeatA{n,m}The pattern repeated n to m times.term
+ stringsA{w₁, w₂, …}Enumerate the language itself: valid, distinct, paginated.strings

Exact answers, in bounded time.

Read the engine source →

Every result is computed, not sampled: when RegexSolver says two patterns are equivalent, that holds for every possible string. And no input pattern, however pathological, can blow up a request.

Deterministic finite automata
Every pattern is compiled to a DFA. Set operations, cardinality, and equivalence are computed on the automaton itself, with no sampling and no approximation.
Immune to ReDoS by construction
There is no backtracking to blow up. Operations run in bounded time under server-side limits, whatever the input pattern looks like.
Open-source Rust core
The automata engine is open-source Rust. The API adds a closed-source layer that turns automata back into compact, readable regex patterns.
FAIR terms for chaining
Any computed result can be returned as a FAIR term — a compact binary automaton you feed straight into the next call, skipping re-parsing entirely.
FIG. 2
A commonly seen email pattern, and what it really accepts
POST /analyze/patternapi.regexsolver.com/v1
TERM([a-zA-Z0-9_.-])+@(([a-zA-Z-])+\.)+([a-zA-Z]{2,4})+
200
a@b.abcdefghijacceptedthe {2,4}+ tail is not "2 to 4" — any length ≥ 2 passes
user+tag@acme.iorejectedno + in the local part

Use it from your language.

Quickstart guide →

Official SDKs for JavaScript, Python, and Java — or call the REST API directly from anything that speaks HTTP.

import { RegexSolverClient, Term } from 'regexsolver';

const client = new RegexSolverClient({
  apiToken: 'REGEXSOLVER_API_TOKEN',
});

// 1. Define a complex base policy (e.g., any internal API path)
const internalApi = Term.regex("/api/v[12]/[a-z]+(/.*)?");

// 2. Define forbidden patterns (e.g., no 'admin' or 'debug' segments)
const forbidden = Term.regex(".*/(admin|debug|private)/.*");

// 3. Compute 'Set Difference': Allow the API but EXCLUDE any forbidden paths
// This is mathematically complex to write as a single regex manually!
const securePolicy = await client.difference(internalApi, forbidden);

// 4. Analyze the security of the new policy
console.log("Secure Pattern:", await client.getPattern(securePolicy));
console.log("Is it empty?", await client.isEmpty(securePolicy));

// 5. Generate 'Safe' test cases that are guaranteed NOT to hit forbidden paths
const safePaths = await client.generateStrings(securePolicy, 5, 0);
console.log("Safe Test Paths:", safePaths);

// 6. Fast client-side enforcement
console.log("Allow '/api/v1/users'?", securePolicy.matches("/api/v1/users"));   // true
console.log("Allow '/api/v1/admin'?", securePolicy.matches("/api/v1/admin/")); // false

Start building in minutes.

10,000 req/month · full access · no payment details needed

Frequently asked questions

How is RegexSolver different from a regex engine or validator?

A regex engine answers one question: does this string match? RegexSolver treats patterns as mathematical sets and answers structural questions without running any strings through them: "do these two rules overlap?", "is this validator too permissive?", or "what strings exist in A but not B?"

Think of it as static analysis for your patterns: it inspects what they can match without ever executing them on real data.

What's the difference between the RegexSolver engine and the RegexSolver API?

The RegexSolver engine is the open-source Rust library that implements the core set-algebra algorithms over finite automata; you can use it directly in your own Rust code.

The RegexSolver API builds on top of that engine and is exposed as a language-agnostic REST API, callable with any HTTP client, your own wrapper, or our official SDKs (JavaScript/TypeScript, Python, Java).

It also adds its own closed-source engine that converts automata back into compact, readable regex patterns, a capability the open-source library does not include.

Which regex syntax is supported? Can I use lookaheads or backreferences?

RegexSolver supports standard character classes, quantifiers, alternation, anchors, and groups: the core constructs of pure regular languages.

Lookaheads, lookbehinds, and backreferences are not supported because they introduce context-sensitivity that makes set operations (intersection, complement, cardinality) undecidable. Keeping to pure regular languages is what makes the mathematical guarantees possible.

Can I chain the output of one operation into another?

Yes, and this is one of RegexSolver's key strengths. Every compute operation can return a FAIR term (Fast Automaton Internal Representation), a compact binary encoding of the resulting automaton.

You can pass FAIR terms directly into subsequent API calls, skipping regex re-parsing and preserving all intermediate state with no overhead.

Is it fast enough for production? Is it vulnerable to ReDoS?

The core engine is written in Rust and operates on deterministic finite automata, which are immune to catastrophic backtracking (ReDoS) by construction. Every operation runs in bounded time.

For high-throughput runtime matching, the recommended pattern is to compute and cache an optimized regex with /analyze/pattern, then match it locally using your language's native engine; the SDKs include a client-side matches() method that does exactly this.

Which languages and platforms are supported?

RegexSolver exposes a language-agnostic REST API, so any HTTP client works.

Official idiomatic SDKs are available for JavaScript/TypeScript (npm), Python (pip), and Java (Maven). All three are open-source and generated from the same OpenAPI spec.

What does the free tier include?

The free tier covers 10,000 monthly API requests, enough for development, prototyping, and small-scale projects. Signing up requires no payment details of any kind.

See the pricing page for the full breakdown of limits.