在网络应用开发中,IP地址验证是常见需求,尤其是确保输入的IP格式正确。本文将介绍如何利用正则表达式匹配和验证IPv4和IPv6地址,并分析每个正则表达式的结构和原理。
1. IPv4 地址的正则表达式
IPv4地址由四组数字组成,每组数字在0到255之间,以句点(.)分隔。IPv4的标准格式是“x.x.x.x”,其中每个x都是一个0到255之间的整数。
正则表达式
^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$
正则表达式分解
- ^:表示字符串的开始。
- ((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}:匹配前三段数字,每段后跟一个句点。
- 25[0-5]:匹配250到255。
- 2[0-4]\d:匹配200到249。
- [01]?\d\d?:匹配0到199。
- (25[0-5]|2[0-4]\d|[01]?\d\d?):匹配第四段数字(不跟句点)。
- $:表示字符串的结尾。
工作原理
该正则表达式通过多重选择结构(|)匹配每段IPv4地址中的数字,保证每段数值处于合法范围(0-255)。前三段数字后跟句点,最后一段直接结束,确保输入符合IPv4格式。
2. IPv6 地址的正则表达式
IPv6地址由8组4位十六进制数字组成,以冒号(:)分隔,例如2001:0db8:85a3:0000:0000:8a2e:0370:7334。IPv6还支持简写,例如::1
代表回环地址。IPv6可以混合IPv4格式,比如::ffff:192.168.1.1。
正则表达式
^([\da-fA-F]{1,4}:){6}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^::([\da-fA-F]{1,4}:){0,4}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^([\da-fA-F]{1,4}:):([\da-fA-F]{1,4}:){0,3}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^([\da-fA-F]{1,4}:){2}:([\da-fA-F]{1,4}:){0,2}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^([\da-fA-F]{1,4}:){3}:([\da-fA-F]{1,4}:){0,1}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^([\da-fA-F]{1,4}:){4}:((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^([\da-fA-F]{1,4}:){7}[\da-fA-F]{1,4}$|^:((:[\da-fA-F]{1,4}){1,6}|:)$|^[\da-fA-F]{1,4}:((:[\da-fA-F]{1,4}){1,5}|:)$|^([\da-fA-F]{1,4}:){2}((:[\da-fA-F]{1,4}){1,4}|:)$|^([\da-fA-F]{1,4}:){3}((:[\da-fA-F]{1,3}|:)$|^([\da-fA-F]{1,4}:){4}((:[\da-fA-F]{1,2}|:)$|^([\da-fA-F]{1,4}:){5}:([\da-fA-F]{1,4})?$|^([\da-fA-F]{1,4}:){6}:$
正则表达式分解
由于IPv6的多种简写可能性,该正则表达式较复杂,分为以下几部分:
- 标准IPv6格式
- ^([\da-fA-F]{1,4}:){7}[\da-fA-F]{1,4}$:匹配完整的8段格式(无简写)。
- IPv4混合格式
- 类似 ::ffff:192.168.1.1 的IPv4地址嵌入。
- ^([\da-fA-F]{1,4}:){6}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$:6段IPv6加1段IPv4地址。
- 简写格式
- ^::([\da-fA-F]{1,4}:){0,4}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$:允许最开头省略的冒号::,后面可跟0到4段IPv6。
- ^[\da-fA-F]{1,4}:((:[\da-fA-F]{1,4}){1,5}|:)$:允许前几段IPv6并带有省略号
::
。
工作原理
IPv6正则表达式通过多种方式处理了不同的简写情况。使用:
符号和16进制字符匹配IPv6的每段,还支持混合格式,满足多种IPv6地址写法。
3. 使用场景与示例
使用方法
在编程中可以直接利用正则表达式匹配字符串,如在Java中使用Pattern类:
import java.util.regex.Pattern;
public class IPValidator {
private static final Pattern IPV4_PATTERN = Pattern.compile("^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$");
private static final Pattern IPV6_PATTERN = Pattern.compile("^([\\da-fA-F]{1,4}:){6}((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$|^::([\\da-fA-F]{1,4}:){0,4}((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$|^([\\da-fA-F]{1,4}:):([\\da-fA-F]{1,4}:){0,3}((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$|^([\\da-fA-F]{1,4}:){2}:([\\da-fA-F]{1,4}:){0,2}((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$|^([\\da-fA-F]{1,4}:){3}:([\\da-fA-F]{1,4}:){0,1}((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$|^([\\da-fA-F]{1,4}:){4}:((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$|^([\\da-fA-F]{1,4}:){7}[\\da-fA-F]{1,4}$|^:((:[\\da-fA-F]{1,4}){1,6}|:)$|^[\\da-fA-F]{1,4}:((:[\\da-fA-F]{1,4}){1,5}|:)$|^([\\da-fA-F]{1,4}:){2}((:[\\da-fA-F]{1,4}){1,4}|:)$|^([\\da-fA-F]{1,4}:){3}((:[\\da-fA-F]{1,4}){1,3}|:)$|^([\\da-fA-F]{1,4}:){4}((:[\\da-fA-F]{1,4}){1,2}|:)$|^([\\da-fA-F]{1,4}:){5}:([\\da-fA-F]{1,4})?$|^([\\da-fA-F]{1,4}:){6}:$");
public static boolean isValidIPv4(String ip) {
return IPV4_PATTERN.matcher(ip).matches();
}
public static boolean isValidIPv6(String ip) {
return IPV6_PATTERN.matcher(ip).matches();
}
public static void main(String[] args) {
System.out.println(isValidIPv4("192.168.1.1")); // true
System.out.println(isValidIPv6("2001:0db8:85a3:0000:0000:8a2e:0370:7334")); // true
}
}
示例结果
- IPv4有效示例:192.168.1.1, 255.255.255.255
- IPv4无效示例:256.100.1.1, 123.456.78.90
- IPv6有效示例:2001:0db8:85a3:0000:0000:8a2e:0370:7334, ::1
- IPv6无效示例:2001:db8::85a3::8a2e:370:7334(多重::简写)
总结
理解和编写IP地址的正则表达式可以帮助我们在开发中处理IP验证需求。IPv4的格式相对简单,但IPv6的灵活性带来了正则的复杂性。这些正则表达式可以帮助确保输入的IP地址符合标准格式,为网络应用提供