1. 程式人生 > >JAVA正則表示式區分IPv4和IPv6地址

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塊)