How to generate a regex from accepted and rejected examples
Derive a bounded JavaScript regular expression from a written format contract, paired match and non-match examples, and adversarial tests.
Do not infer a pattern from positive examples alone. Write the field's format contract, choose the exact regex engine, decide whether the whole string or a substring must match, and pair every accepted example with a nearby rejected one. Build the smallest pattern that explains those boundaries, then test empty, long, Unicode and adversarial inputs in the destination engine while keeping semantic and authorization checks outside the regex.

Write the contract before the pattern
Name the destination engine and version, the exact field being matched, whether the match covers the whole input, and the permitted character, length and normalization rules. State whether matching is case-sensitive and multiline. Engine choice matters because JavaScript, PCRE, RE2, .NET and database dialects do not share every feature or performance property.
- Choose full-string validation or substring extraction.
- List the allowed character repertoire and separators.
- Set minimum and maximum lengths outside or inside the pattern.
- Record case, Unicode normalization and line-break policy.
Build accepted and rejected minimal pairs
For each intended rule, keep one accepted string beside the smallest change that should fail: a missing character, extra separator, wrong case or value just outside a length bound. Add empty, whitespace-only, longest-valid, first-invalid, punctuation and representative Unicode inputs. Positive examples show possibilities; negative examples reveal the boundary.
Compose the smallest explainable expression
Start with input-boundary assertions when the entire string must conform. Add explicit character classes, then bounded repetition and grouping only where the contract needs them. Prefer an allowlist for structured fields. Escape literal user-supplied fragments before constructing a dynamic pattern, and use a parser or fixed set comparison when those express the data more clearly.
Run the corpus in the destination engine
Execute every example with the same flags and API the application will use. Add long matching strings and long near-misses, especially after repeated groups or overlapping alternatives. Measure rather than assuming performance; crafted input can make some backtracking expressions consume excessive time.
Separate shape, meaning and security decisions
A regex can establish a syntactic shape, not whether a date exists, an identifier is available, a URL is safe to fetch or a user is authorized. Apply semantic checks after the format check. For untrusted requests, enforce validation on the server even when a client-side pattern improves feedback.
Check the primary references
Check the source against the result
The shipped slug recipe is tested with mcxai-tools, Bad Slug and docs-v2. The intended contract is lowercase ASCII letters or digits separated by single hyphens, with the entire input required to conform.
/^[a-z0-9]+(?:-[a-z0-9]+)*$/ returns MATCH for mcxai-tools and docs-v2, and NO MATCH for Bad Slug. The anchors cover the whole input; the repeated group permits additional non-empty hyphenated segments.
Those three outcomes do not prove that the pattern covers every desired slug, imposes a suitable maximum length, accepts internationalized labels, behaves identically outside JavaScript or makes a string safe to use as a path. Add contract-specific examples and destination checks before deployment.
Test one of six reviewed JavaScript recipes
Choose a bounded slug, integer, decimal, hex-color, date-shape or identifier pattern and inspect every supplied sample's exact result locally.
Open Regex Generator and Tester