[NTTP]
Developers

How to describe a regex in plain English and get one that works

August 23, 2026 · 4 min read

Most people who need a regex do not actually want to learn regex. They have one job: match this, reject that. The fastest route there is not memorising lookahead syntax, it is describing the problem clearly enough that whatever writes the pattern for you gets it right the first time, for the specific language you are using.

Say what you want, not what you think the regex should look like

Do not try to speak in regex before you know regex. “A UK postcode” or “a line that starts with a number followed by a colon” is a better brief than a half-remembered character class. The description just needs to be unambiguous about the shape: is whitespace allowed, is it case sensitive, does it need to match the whole line or just a part of it.

Name the language, every time

This is the step most people skip, and it is the one that breaks the result. JavaScript, Python, PCRE, and POSIX are not the same language wearing different clothes. Python needs fixed-width lookbehind where PCRE is looser. POSIX has no named groups, no lookahead, and no non-greedy quantifiers at all, so a pattern written for grep -E cannot lean on any of those tricks. A pattern that is valid in one flavor can silently fail, or worse, silently match the wrong thing, in another.

Test it against your own examples

The single highest-value thing you can add to a plain-English request is a handful of real examples: strings that should match, and strings that should not. A generic one-line ask has no way to catch a subtle miss, like a postcode pattern that happens to reject a real postcode with an unusual format. Giving explicit test cases turns a guess into something that has actually been checked.

Plain-English description: "a valid email address" Language: JavaScript Should match: dave@example.com, first.last+tag@sub.example.co.uk Should not match: dave@, @example.com, dave example.com Pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/ Explanation: ^ and $ anchor the match to the whole string, so nothing before or after counts. [^\s@]+ before the @ requires one or more characters that are not whitespace and not another @, which is the local part. The literal @ separates it from the domain. [^\s@]+\.[^\s@]+ after that requires a domain with at least one dot, so a bare "@example" with no top-level domain is rejected. This is a practical, permissive email check, not a full RFC 5322 validator; it will accept some addresses that are technically invalid and reject a few rare but valid ones, which is the normal trade-off for form validation.

Common mistakes

← All guides