Fixtures that can't drift from the validator.

Hand-written fixtures rot the moment the pattern changes. Generate the strings from the pattern itself: distinct, deterministic, paginated. Test data and validator can never disagree.

Run it on your patterns.

Each card calls the real API. Edit the patterns and compute. No signup.

Fixtures from the format you already wroteOPEN IN LIVE DEMO →
A =
strings(A, limit: , offset: )
STRINGS["beta-0000", "beta-0001", "beta-0002", "beta-0003", "beta-0004"]
Same order every run: page with offsetOPEN IN LIVE DEMO →
A =
strings(A, limit: , offset: )
STRINGS["abcde", "abcabc"]
Only strings inside a length window
A =(ab|cde)*
strings(A, limit: 5, minLength: 4, maxLength: 6)
STRINGS["abab", "cdeab", "abcde", "ababab", "cdecde"]
Every case a finite format allowsOPEN IN LIVE DEMO →
A =
strings(A, limit: , offset: )
STRINGS["000", "001", "010", "011", "100", "101", "110", "111"]
OperationNotationAnswersReturns
strings{s ∈ A}Distinct strings the pattern matches, paginated by limit/offset.string[]

Parameters

ParameterValuesMeaning
limit1 to 100Maximum number of distinct strings to return in the call. The example cards above and the live demo cap it at 10.
offsetintegerStrings to skip before collecting, which is how you paginate.
minLengthintegerLower bound of the length window; excluded strings never consume offset positions.
maxLengthintegerUpper bound of the length window.
pathOrdersweep · interleave · shuffledWhich paths of the language are expanded first.
characterOrderascending · shuffledHow each position is filled from its character range.
seedintegerDraws both shuffled orders, so a shuffled run stays reproducible.
charsetcharacter classRestricts generation to a character class such as [a-z]; paths needing anything else are dropped.

Code example.

Every operation on this page, called through the official SDK.

import { RegexSolverClient, Term } from 'regexsolver';

const client = new RegexSolverClient({ apiToken: 'REGEXSOLVER_API_TOKEN' });
const term = Term.regex("(alpha|beta|prod)-[a-z0-9]{4}");

// Distinct fixtures straight from the format you already wrote
await client.generateStrings(term, 5, 0);
// ["beta-0000", "beta-0001", "beta-0002", "beta-0003", "beta-0004"]

// Offset pages through the language, no repeats, no gaps. Offsets only line up
// from page to page on a deterministic term, and a term built from a pattern
// isn't one, so determinize it once before the first page.
const bits = await client.determinize(Term.regex("[01]{3}"));
const all = [];
for (let offset = 0; ; offset += 3) {
  const page = await client.generateStrings(bits, 3, offset);
  all.push(...page);
  if (page.length < 3) break;
}
// ["000", "001", "010"], then ["011", "100", "101"], then ["110", "111"]

// Only strings inside a length window; excluded ones never consume offset
await client.generateStrings(Term.regex("(ab|cde)*"), 5, 0, { minLength: 4, maxLength: 6 });
// ["abab", "cdeab", "abcde", "ababab", "cdecde"]

// Keep output printable when the pattern allows all of Unicode
await client.generateStrings(Term.regex("[a-z]{3}"), 5, 0, { charset: "[a-c]" });

// Realistic-looking data, still reproducible: same seed, same strings
await client.generateStrings(term, 5, 0, {
  pathOrder: "shuffled", characterOrder: "shuffled", seed: 42,
});