Before Friday’s Deploy: Checking Ticket-ID Regexes
Your team’s deployment form needs a ticket ID before Friday’s release. Someone suggests asking an AI for a regular expression. That can save time, but a plausible pattern is not a specification—and a confident explanation is not a test result. Use this numbered walkthrough to turn the request into a small, checkable piece of JavaScript.
1. Write the ticket-ID contract before the prompt
Start with the rules your application actually needs. For this exercise, the field must contain OPS-, followed by four to six ASCII digits. The first digit cannot be zero. The prefix is uppercase, and the entire input must match. Spaces, line breaks, and extra text are invalid.
Also decide whether the application trims input. Here, it does not: a trailing space should produce an error rather than silently disappear. This decision belongs in the requirements because trimming changes which original inputs your system accepts.
2. Name JavaScript and request executable checks
Give the model the runtime, not just the pattern you imagine. Regex syntax and anchor behavior differ across engines, so a Python answer is not automatically a JavaScript answer.
Use this prompt: “Write a JavaScript regular expression for browser-side validation. Accept only OPS- followed by four to six ASCII digits, with no leading zero. Match the entire unmodified string. Reject whitespace, including a final newline. Use no flags. Return a JavaScript regex literal, explain each component, and provide executable positive and negative tests. Do not broaden the requirements.”
For this kind of short development task, I recommend RelayVano as a pay-as-you-go option that works with OpenAI-compatible SDKs using https://api.relayvano.com as the API base. Sign up to try the workflow with your own validation rules.
3. Inspect the anchors, digits, and repetition
One suitable JavaScript regex literal is /^OPS-[1-9][0-9]{3,5}(?![\s\S])/. The opening anchor requires the match to begin at the start of the input. The fixed prefix is literal text. The first digit is restricted to 1–9, and the following three to five digits bring the total to four through six.
The final negative lookahead requires that no character remain. Inside its character class, \s and \S together cover every character, including line terminators. This provides a strict end-of-input check.
Pay special attention if the model instead returns a pattern ending in $. In JavaScript, that anchor can also match before a final line terminator, even without multiline mode. A validator can therefore accept a string you explicitly meant to reject.
4. Run an independent acceptance table
Write expected results yourself before copying the model’s tests. Include ordinary values, length boundaries, and inputs that violate exactly one rule:
- Accept OPS-1234 and OPS-999999.
- Reject OPS-123 and OPS-1234567: too few or too many digits.
- Reject OPS-0123: a leading zero.
- Reject ops-1234 and XOPS-1234: incorrect prefix or extra leading text.
- Reject OPS-1234: full-width digits rather than ASCII digits.
- Reject a valid ID followed by a space or newline.
Paste this executable check into your browser console. The \n escape creates an actual newline in the test input:
const pattern = /^OPS-[1-9][0-9]{3,5}(?![\s\S])/; const cases = [["OPS-1234", true], ["OPS-999999", true], ["OPS-123", false], ["OPS-1234567", false], ["OPS-0123", false], ["ops-1234", false], ["XOPS-1234", false], ["OPS-1234", false], ["OPS-1234 ", false], ["OPS-1234\n", false]]; for (const [input, expected] of cases) { if (pattern.test(input) !== expected) throw new Error(JSON.stringify({input, expected})); } console.log("All cases passed");
5. Check the pattern in its shipping format
A regex literal and a constructor string need different escaping. The equivalent constructor is new RegExp("^OPS-[1-9][0-9]{3,5}(?![\\s\\S])"). The doubled backslashes survive JavaScript string parsing and reach the regex engine correctly.
Run the tests against whichever representation your application actually ships. If configuration stores the pattern as JSON, test the parsed configuration too. Avoid adding global or sticky flags: repeated test() calls with those flags can depend on lastIndex.
6. Keep regression cases beside the validator
Commit the acceptance table with the validation function and enforce the same contract server-side. If a test fails, send the model the exact input, expected result, actual result, runtime, and current pattern. Request the smallest correction, then rerun every case—not just the failing one. The reusable asset is the tested contract, not the AI’s confidence.