//IPv6 address validator matches these IPv6 formats
//::ffff:21:7.8.9.221 | 2001:0db8:85a3:08d3:1319:8a2e:0370:7344
//| ::8a2e:0:0370:7344 | 2001:0db8:85a3:08d3:1319:8a2e:100.22.44.55
//| 2001:0db8::8a2e:100.22.44.55 | ::100.22.44.55 | ffff::
//And such addresses are invalid
//::8a2e:0:0370:7344.4 | 2001:idb8::111:7.8.9.111 | 2001::100.a2.44.55
//| :2001::100.22.44.55
public static boolean isIPV6Format(String ip) {
ip = ip.trim();
//in many cases such as URLs, IPv6 addresses are wrapped by []
if(ip.substring(0, 1).equals("[") && ip.substring(ip.length()-1).equals("]"))
ip = ip.substring(1, ip.length()-1);
return (1 < Pattern.compile(":").split(ip).length)
//a valid IPv6 address should contains no less than 1,
//and no more than 7 ":” as separators
&& (Pattern.compile(":").split(ip).length <= 8)
//the address can be compressed, but "::” can appear only once
&& (Pattern.compile("::").split(ip).length <= 2)
//if a compressed address
&& (Pattern.compile("::").split(ip).length == 2)
//if starts with "::” – leading zeros are compressed
? (((ip.substring(0, 2).equals("::"))
? Pattern.matches("^::([\\da-f]{1,4}(:)){0,4}(([\\da-f]{1,4}(:)[\\da-f]{1,4})
|([\\da-f]{1,4})|((\\d{1,3}.){3}\\d{1,3}))", ip)
: Pattern.matches("^([\\da-f]{1,4}(:|::)){1,5}
(([\\da-f]{1,4}(:|::)[\\da-f]{1,4})|([\\da-f]{1,4})
|((\\d{1,3}.){3}\\d{1,3}))", ip)))
//if ends with "::" - ending zeros are compressed
: ((ip.substring(ip.length()-2).equals("::"))
? Pattern.matches("^([\\da-f]{1,4}(:|::)){1,7}", ip)
: Pattern.matches("^([\\da-f]{1,4}:){6}(([\\da-f]{1,4}
:[\\da-f]{1,4})|((\\d{1,3}.){3}\\d{1,3}))", ip));
}}
6、如何正规化 IPv6 地址
在网络程序开发中,经常使用 IP 地址来标识一个主机,例如记录终端用户的访问记录等。由于 IPv6 具有有零压缩地址等多种表示形式,因此直接使用 IPv6 地址作为标示符,可能会带来一些问题。
为了避免这些问题,在使用 IPv6 地址之前,有必要将其正规化。
除了通过我们熟知的正则表达式,笔者在开发过程中发现使用一个简单的 Java API 也可以达到相同的效果。