Ask ChatGPT for a regex with examples that can prove it wrong

The pattern ChatGPT gives you matches your first filename, then accepts a backup file you meant to exclude. Supply both valid and invalid examples before asking for the regex, and name the engine and operation. A filename filter in JavaScript needs different decisions from extracting a matching fragment inside a longer message.

Start with the rule in ordinary language. Once that rule is settled, ask for a pattern, a runnable test, and an explanation of the boundary cases. OpenAI recommends specific context and revising requests from the observed response; the test cases make that revision concrete. Prompting guidance

Specify what one match means

Suppose a fictional upload process accepts reports named report-YYYY-MM.csv. It allows years beginning with 20 and months 01 through 12. The name must be lowercase, with no spaces or extra suffix. This is a filename policy, not a check that a real report exists.

The following examples expose several different mistakes:

Filename Expected Reason
report-2026-01.csv Accept Allowed year and month
report-2026-12.csv Accept Upper month boundary
report-2026-00.csv Reject Month zero
report-2026-13.csv Reject Month beyond twelve
report-1999-01.csv Reject Outside the chosen year policy
report-2026-1.csv Reject Month needs two digits
Report-2026-01.csv Reject Case differs
xreport-2026-01.csv Reject Extra prefix
report-2026-01.csv.bak Reject Extra suffix
report-2026-01Xcsv Reject The extension needs a literal dot

If your real filenames allow uppercase letters, spaces, or a different year range, change the policy and examples first. Quietly trimming input or adding case-insensitive matching changes which values the application accepts.

Copy the rule and the examples into the request

Write a JavaScript regex for validating an entire filename.
Use RegExp.test with no global, sticky, multiline, or ignore-case flags.

Policy:
Exact lowercase report-YYYY-MM.csv.
YYYY is four ASCII digits beginning with 20.
MM is 01 through 12. No whitespace, extra prefix, or extra suffix.
Do not trim or normalize the input. Newlines must fail.

Must pass: report-2026-01.csv, report-2026-12.csv
Must fail: report-2026-00.csv, report-2026-13.csv,
report-1999-01.csv, report-2026-1.csv, Report-2026-01.csv,
xreport-2026-01.csv, report-2026-01.csv.bak,
report-2026-01Xcsv, and a valid-looking name followed by a newline.

Return a regex literal, explain each part, and provide runnable
JavaScript tests with expected and actual booleans. Also show the
equivalent RegExp constructor string so backslash escaping is clear.
Explain any unmet requirement. Do not claim that matching the name
proves the file exists or contains valid CSV.

Run the pattern in the engine your application uses

For that policy, this authored example uses an explicit end-of-input assertion:

const filenamePattern =
  /^report-20[0-9]{2}-(?:0[1-9]|1[0-2])\.csv(?![\s\S])/;

const cases = [
  ["report-2026-01.csv", true],
  ["report-2026-12.csv", true],
  ["report-2026-00.csv", false],
  ["report-2026-13.csv", false],
  ["report-1999-01.csv", false],
  ["report-2026-1.csv", false],
  ["Report-2026-01.csv", false],
  ["xreport-2026-01.csv", false],
  ["report-2026-01.csv.bak", false],
  ["report-2026-01Xcsv", false],
  ["report-2026-01.csv\n", false],
];

for (const [input, expected] of cases) {
  const actual = filenamePattern.test(input);
  console.log({ input, expected, actual, passed: actual === expected });
}

The year portion accepts 2000–2099 under this policy. The month alternatives accept 01–09 or 10–12. The escaped dot matches the dot before csv. At the end, (?![\s\S]) requires that no character remains, including a newline. JavaScript's $ can also match before a final line terminator, so that boundary deserves a test when the whole raw input must match. MDN's JavaScript RegExp reference

The constructor needs another level of backslash escaping because its pattern is inside a JavaScript string:

const filenamePattern = new RegExp(
  "^report-20[0-9]{2}-(?:0[1-9]|1[0-2])\\.csv(?![\\s\\S])"
);

Use either declaration, rather than pasting both into the same scope. The RegExp constructor explanation covers the string-versus-literal distinction; RegExp.test covers the boolean check.

Send a failure back as a small reproducible case

If one test fails, send ChatGPT the exact pattern, engine, flags, input, expected result, and observed result. Ask it to correct that case while keeping every accepted case passing. An explanation that sounds right is still only a proposed fix until you run the tests again.

Keep the agreed examples beside the accepted pattern in your application. When the filename policy changes, update those examples before changing the regex, then check actual CSV content in a separate validation step.

Keep reading