Java regex for accepting a valid hostname,IPv4, or IPv6 address

I understand that you may be forced to use a regex. However, if possible it is better to avoid using regexes for this task and use a Java library class to do the validation instead.

If you want to do validation and DNS lookup together, then InetAddress.getByName(String) is a good choice. This will cope with DNS, IPv4 and IPv6 in one go, and it returns you a neatly wrapped InetAddress instance that contains both the DNS name (if provided) and the IPv4 or IPv6 address.

If you just want to do a syntactic validation, then Apache commons has a couple of classes that should do the job: DomainValidator and InetAddressValidator.


Guava has a new class HostSpecifier. It will even validate that the host name (if it is a host name) ends in a valid "public suffix" (e.g., ".com", ".co.uk", etc.), based on the latest mozilla public suffix list. That's something you would NOT want to attempt with a hand-crafted regex!


As others have said, doing this with a regex is quite a challenge and not advisable. But it is easy to do with the IPAddress Java library which can parse host names, IPv4 and IPv6 addresses, without triggering DNS lookup. Disclaimer: I am the project manager of that library.

Sample code:

check("1.2.3.4");
check("::1");
check("a.b.com");

static void check(String hostStr) {
    HostName host = new HostName(hostStr);
    try {
        host.validate(); // triggers exception for invalid
        if(host.isAddress()) {
            IPAddress address = host.asAddress();
            System.out.println(address.getIPVersion() + " address: " + address);
        } else {
            System.out.println("host name: " + host);
        }
    } catch(HostNameException e) {
        System.out.println(e.getMessage());
    }
}

Output:

IPv4 address: 1.2.3.4
IPv6 address: ::1
host name: a.b.com