Write a regex from plain English with tests
Describe what to match and give examples. Get a regular expression for your language, explained piece by piece, with tests that should and should not pass.
How to use it
- Say where it will run JavaScript, Python, PCRE, .NET or a tool like VS Code search. Flavours differ.
- Give real examples Three strings that must match and three that must not. Edge cases are where regexes break.
- Run the tests Paste the pattern and the test list into regex101.com (pick your flavour) before using it.
- Prefer a parser when it's complex For emails, HTML or dates with real rules, use a library — the answer will say when.
The prompt
You are a careful developer. Write a regular expression for me.
Where it will run (language or tool and version): [REGEX_FLAVOUR]
What it should match, in plain words: [WHAT_TO_MATCH]
Examples that must match: [MATCH_EXAMPLES]
Examples that must not match: [NON_MATCH_EXAMPLES]
Return:
- The regex, with the flags, as a code block, plus a code snippet showing how to use it in my language.
- A piece-by-piece explanation.
- A test table of at least 10 strings — my examples plus edge cases you think of — with "should match" and "does match" columns. Check each one carefully against the pattern; if any fails, fix the pattern before answering.
- Limits: what it deliberately does not handle, and whether a parser or library would be safer for this job.Prefer readable patterns over clever ones. Anchor the pattern if it validates a whole value; avoid patterns that risk catastrophic backtracking.
Example result
The pattern
^(?:\+61 ?4|04)\d{2} ?\d{3} ?\d{3}$
const AU_MOBILE = /^(?:\+61 ?4|04)\d{2} ?\d{3} ?\d{3}$/;
AU_MOBILE.test(input.trim()); // true or false
Piece by piece
^…$— the whole value must be the number, nothing before or after.(?:\+61 ?4|04)— either+61(optional space) then4, or the local04. Australian mobiles start with 4 after the country code, and you drop the 0 when using +61.\d{2}— the next two digits (e.g.12in 0412).?\d{3}— optional space, three digits.?\d{3}— optional space, the last three digits.
Tests
| Input | Should match | Does match |
|---|---|---|
0412 345 678 | ✅ | ✅ |
0412345678 | ✅ | ✅ |
+61 412 345 678 | ✅ | ✅ |
+61412345678 | ✅ | ✅ |
0412 345678 | ✅ | ✅ |
(02) 9876 5432 | ❌ landline | ❌ |
0412 345 67 | ❌ too short | ❌ |
+61 0412 345 678 | ❌ extra 0 after +61 | ❌ |
0512 345 678 | ❌ not a mobile prefix | ❌ |
04123 45678 | ❌ odd grouping | ❌ |
0412-345-678 | ❌ dashes | ❌ |
0412 345 678 | ❌ leading space | ❌ (that's why the snippet uses trim()) |
Limits
- Dashes and brackets aren't accepted. If users type
0412-345-678, either strip non-digits first (input.replace(/[\s-]/g, '')) and validate^(?:\+614|04)\d{8}$, or extend the pattern. - It checks the format, not whether the number exists.
- Groupings other than 4-3-3 (like
04123 45678) are rejected on purpose; relax the spaces to?between every digit if you want to accept any grouping. - For international numbers in general, use a library such as libphonenumber rather than a regex.