Domain Regex
Regex for validating domain names and subdomains.
^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$About this pattern
This validates a domain name as a series of labels separated by dots, ending in an alphabetic top-level domain of at least two characters. Each label may run 1 to 63 characters and may contain hyphens internally but not at either end — a constraint straight from the DNS specification, and the reason ([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])? is wrapped the way it is rather than written as a simple character class.
The leading and trailing hyphen restriction is not pedantry. Labels beginning with "xn--" are how internationalised domains are encoded in Punycode, and permitting arbitrary leading hyphens muddies that convention.
The pattern accepts any alphabetic TLD rather than checking against a list, which is the right call — the TLD list is now long, changes regularly, and hard-coding it guarantees the pattern goes stale. What it does not accept is a protocol, a path, or a port, so "https://example.com/page" fails; that is a URL, and url-regex handles it. Regex checks shape, never existence — a well-formed value can still be entirely fictional. A domain matching this pattern may be unregistered, expired, or parked.
Worked examples
Matches
- example.com
- sub.example.co.uk
Does not match
- -example.com
- example
- http://example.com
FAQ
Why can a label not start or end with a hyphen?
The DNS specification forbids it. It also keeps the "xn--" Punycode prefix, which marks an internationalised domain, meaningful as a convention.
Does this check the TLD is real?
No, and deliberately. The TLD list is long and changes regularly, so hard-coding it guarantees the pattern goes stale. Any alphabetic TLD of two or more characters is accepted.
Will it match a full URL?
No. A protocol, path, or port causes it to fail, because those belong to a URL rather than a domain. Use the URL pattern for that.