JAVA正则表达式区分IPv4和IPv6地址

PS*代码直接见第二部分:

一、进入正题前先说说JAVA正则表达式相关概念:

1、常用字符类:

[abc] == a||b||c   [a-zA-Z] == 所有大小写字母中的任意一个      [0-9A-Za-z] == 任意一个字母或者数字

。。。。。。懒得打字了,直接上截图(Think in Java)

2、常用逻辑操作符、边界匹配符

3、量词(常用)

4、常用表达式以及意义:

?     示例:(X)?       0个或1个X

+     示例:(X)+       1个或多个X

*     示例:(X)*        0个或多个X

5、Pattern和Matcher类

这两个类上手使用比较简单,学习JAVA正则表达式建议仔细读一读

PS* 一定请注意     '?:'   非获取匹配,匹配冒号后的内容但不获取匹配结果,不进行存储供以后使用,在不想被捕获的时候使用 可以提高程序执行速度

比如有正则表达式,正则表达式开头出现的 '?:' 你可以把它理解成一个开关,写上它将不进行存储,可以提高执行速度,但是不能反向引用了;如果你只是想要匹配这个功能是可以大胆的写在开头的;但是如果你想要使用一些其它的中间结果,那么就不能使用这个开关了。

Pattern regexs = Pattern.compile("^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$");

二、JAVA正则表达式区分IPv4和IPv6地址

输入数据合法格式:

IPv4:唯一标准格式 -> 0-255.0-255.0-255.0-255

IPv6: 标  准  格  式 -> abcd:abcd:abcd:abcd:abcd:abcd:abcd:abcd

IPv6  压  缩  格  式 -> abcd::abcd:abcd:abcd:abcd

                                   ::abcd:abcd:abcd

                                   abcd:abcd:abcd:abcd:abcd::

                                   ::1

                                   ::

IPv6压缩规则:必需至少两个全0块才可以压缩,且每个IPv6地址只能压缩一次,存在多个可以压缩的位置优先压缩左边的全0块

import java.util.regex.Pattern;
public class JudgeIpAddress {
    
	//功能:判断IPv4地址的正则表达式:
    private static final Pattern IPV4_REGEX = 
        Pattern.compile(
                "^(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}$");
    
    //功能:判断标准IPv6地址的正则表达式
    private static final Pattern IPV6_STD_REGEX = 
        Pattern.compile(
                "^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$");    
    
    //功能:判断一般情况压缩的IPv6正则表达式
    private static final Pattern IPV6_COMPRESS_REGEX = 
        Pattern.compile(
                "^((?:[0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4})*)?)::((?:([0-9A-Fa-f]{1,4}:)*[0-9A-Fa-f]{1,4})?)$");
    
    /*由于IPv6压缩规则是必须要大于等于2个全0块才能压缩
             不合法压缩 : fe80:0000:8030:49ec:1fc6:57fa:ab52:fe69
    ->           fe80::8030:49ec:1fc6:57fa:ab52:fe69
            该不合法压缩地址直接压缩了处于第二个块的单独的一个全0块,
            上述不合法地址不能通过一般情况的压缩正则表达式IPV6_COMPRESS_REGEX判断出其不合法
            所以定义了如下专用于判断边界特殊压缩的正则表达式
    (边界特殊压缩:开头或末尾为两个全0块,该压缩由于处于边界,且只压缩了2个全0块,不会导致':'数量变少)*/
    //功能:抽取特殊的边界压缩情况
    private static final Pattern IPV6_COMPRESS_REGEX_BORDER = 
            Pattern.compile(
                "^(::(?:[0-9A-Fa-f]{1,4})(?::[0-9A-Fa-f]{1,4}){5})|((?:[0-9A-Fa-f]{1,4})(?::[0-9A-Fa-f]{1,4}){5}::)$");
    
    //判断是否为合法IPv4地址
    public static boolean isIPv4Address(final String input){
    	return IPV4_REGEX.matcher(input).matches();
    }
    //判断是否为合法IPv6地址
    public static boolean isIPv6Address(final String input) {
    	int NUM = 0;
    	for(int i = 0;i<input.length();i++){
    		if(input.charAt(i) == ':')NUM++;
    	}
    	if(NUM > 7) return false;
    	if(IPV6_STD_REGEX.matcher(input).matches()){
    		return true;
    		}
    	if(NUM == 7){
    		return IPV6_COMPRESS_REGEX_BORDER.matcher(input).matches();
    	}
    	else{
    		return  IPV6_COMPRESS_REGEX.matcher(input).matches();
    	}
    }
    
    public static void main(String args[])
    {
        String ipAddr = "A00:a00:100:f261::F15";
        //fe80:1295:8030:49ec:1fc6:57fa:0000:0000
        //A00:a00:100::f261:F15
        //fe80:1295:8030:49ec:1fc6:57fa::
        System.out.println(ipAddr);
        if(isIPv6Address(ipAddr)){
        	System.out.println("IPV6地址");
        }
        else if(isIPv4Address(ipAddr)){
        	System.out.println("IPV4地址");
        }
        else{
        	System.out.println("不合法地址");
        }
    }
}

之前看过一个同行类似的帖子,但是那个同行关于处理,压缩的IPv6地址,的正则表达式有一个缺陷:当一个IPv6地址为压缩格式的时候,其正则表达式不能除掉哪些长度超过6块的不合法的IPv6地址(由IPv6最少压缩两个全0块的压缩规则可知,一个被压缩的IPv6地址最多有6块)

猜你喜欢

转载自blog.csdn.net/bokerr/article/details/83508415