日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

正則表達式匹配ip地址超詳細講解_正則表達式

作者:m0_65463546 ? 更新時間: 2022-12-29 編程語言

一、正則匹配基本知識及概念

在練習之前,需要大家知道一些基本知識,如果有一定基礎的可以跳過該步驟,直接往下看。

正則表達式-字符類

[abc]:代表a或者b,或者c字符中的一個。
[^abc]:代表除a,b,c以外的任何字符。
[a-z]:代表a-z的所有小寫字符中的一個。
[A-Z]:代表A-Z的所有大寫字符中的一個。
[0-9]:代表0-9之間的某一個數字字符。
[a-zA-Z0-9]:代表a-z或者A-Z或者0-9之間的任意一個字符。
[a-dm-p]:a 到 d 或 m 到 p之間的任意一個字符。

正則表達式-邏輯運算符

&&:并且
| :或者(可以省略)

正則表達式-預定義字符

“.” : 匹配任何字符。
“\d”:任何數字[0-9]的簡寫;
“\D”:任何非數字[^0-9]的簡寫;
“\s”: 空白字符:[ \t\n\x0B\f\r] 的簡寫
“\S”: 非空白字符:[^\s] 的簡寫
“\w”:單詞字符:[a-zA-Z_0-9]的簡寫
“\W”:非單詞字符:[^\w]

正則表達式-數量詞

x? : 0次或1次
x* : 0次到多次
x+ : 1次或多次
X{n} : 恰好n次
X{n,} : 至少n次
X{n,m}: n到m次(n和m都是包含的,最少n次,最多m次。

二、ip地址匹配

題目要求:使用正則表達式匹配192.11.23.69

須知:ip地址的范圍為0.0.0.0-255.255.255.255

接下來我們直接進入正題吧!在我們看到題目的第一眼,大家可能覺得很簡單,這不就用\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}

zh

這里我們可以看到使用上述表達式的確匹配成功。

雖然完成了我們的題目要求,有些細心的伙伴會發現,用紅色標注出來的部分,重復了三遍,是不是我們可以用分組的方式來簡化表達式并完成題目要求。我們把上面的匹配表達式換成分組之后的樣子,即(\d{1,3}\.){3}\d{1,3}

表達式講解:(\d{1,3}\.) 匹配我們前三段的ip地址和’.‘,因為第四段ip地址最后面不能有’.',如果我們使用在同一個分組去匹配就會出現錯誤情況,而\d{1,3}剛好匹配我們最后一段ip地址

匹配效果如下:

?匹配同樣成功,該模式有什么不對的地方嗎?從語法上看,完全正確,也達到了我們的題目要求,可是我們有沒有注意到,我們日常生活中所用的ip地址每一位都是在0-255之間,但是我們上面寫的表達式會匹配0-999之間的所有ip地址,如果在未來的工作中,有這樣的需求,要匹配所有合法的ip地址,那么我們上面所寫的正則表達式是不是就不符合要求了,這里就需要我們使用子表達式的嵌套(注意:有一點很重要。通過上面的例子,我們發現,寫一個能夠匹配預期內容的正則表達式其實并不難,但是寫一個能夠考慮到所有可能場景,確保將不需要匹配的內容排除在外的正則表達式就困難多了)

?所以我將上面的表達式又改進了一下(這里用到了子表達式的嵌套,如果不懂的小伙伴可以先看一下基本概念再來看接下來的內容)。我們發現當ip地址僅有一位或者兩位的時候(即1.1.1.1 or 11.11.11.11),用(\d{1,2}\.)就可以完成匹配,當ip地址為三位的時候,會有這么兩種情況(這里留下個疑問,考慮到初學者可能犯錯的情況)?

1:ip地址開頭為1的時候,我們后面的兩位每一位的范圍都在0-9之間,而\d這個元字符剛好滿足了我們的要求,所以使用(1\d{2}.)就滿足了我們在100-199ip地址的匹配,這個其實還相對簡單,接下來就是200-255之間ip地址的匹配了,有些同學可能會想,我們可以使用匹配100-199的表達式來實現對200-255ip地址的匹配,即(2\d{2}\.)這樣的表達式來實現,可是這樣會把256-299之間的ip地址匹配到,違反了我們的意愿,所以我改良了一下表達式(2[0-5]{2}\.]),這樣就只會匹配到200-255之間的ip地址,既然子表達式都寫好了,就讓我們來實踐看看效果吧!

表達式為:((1\d{2}.)|(2[0-5]{2}.)|(\d{1,2}.)){3}((\d{1,2})|(1\d{2})|(2[0-5]{2}))),伙伴們可以一起實踐一下!

匹配成功,可是再寫出這個表達式,我們要測試某些特殊情況是否不在我們的匹配范圍內,于是我發現了以下兩個比較重要的問題。

第一種:

合法ip地址匹配錯誤

第二種:

非法ip地址匹配成功

為什么會出現上面的情況?

當我們覺得表達式很完美的時候,雖然256超出匹配范圍,但是因為(\d{1,2}\.)的影響,使得我們的非法表達式也匹配成功,本來192.11.23.200為合法表達式,卻只匹配到了98.11.23.200,請大家看我用紅色箭頭標注的地方,會不會跟我們子表達式的順序有關呢?那好,我來改變一下順序,我們將(\d{1,2}\.)放到了最后,防止出現錯誤匹配

改變匹配順序后的表達式為:
( ( (2[0-5]{2}.)|(1\d{2}.)|(\d{1,2}.)){3}((1\d{2})|(2[0-5]{2})|(\d{1,2})))

果然,第一種情況我們是因為子表達式順序的原因,導致匹配錯誤。

可是第二種情況使用改變順序的表達式,依然會出現以上問題(這里也就印證了上文提到的那些話,要想寫出一個符合規范的表達式就很困難)。

于是這里的^就起到了作用,我們可以把第一個子表達式單另拉出來加上^表示第一段ip地址開頭為(\d{1,2}),這樣剛好避免了我們如上的情況,效果如下:

可以看到非法ip不在我們的匹配當中。

其實寫到這里大家是不是感覺已經大功告成了?回答:No

(2[0-5]{2})這個表達式能否匹配239這個ip呢?不知道有沒有細心的小伙伴發現

所以最終正確的表達式應該為:
(^((2[0-4]\d.)|(25[0-5].)|(1\d{2}.)|(\d{1,2}.))((2[0-5]{2}.)|(1\d{2}.)|(\d{1,2}.){2})((1\d{2})|(2[0-5]{2})|(\d{1,2})))

在這里可以跟大家說一下,是否可以使用$來避免我們上述第一種問題,有興趣的可以嘗試一下

附正則表達式匹配IP地址小結

1. IP段都表示一個字節,即只能在 0~255之間。

所以一個正確的IP應該是:(0~255) .(0~255) .(0~255) .(0~255)

通過觀察可以發現可以將整個IP分為兩部分匹配,即:(0~255) 和 .(0~255) 3次

2. 0~255可以分兩部分匹配 0~199 和 200~255

a) 0~199 正則表達式為 [0-1]?\d{1,2}

[0-1]? 表示匹配 0或1一次或零次

\d 表示匹配任意一個十進制數字,即 0~9

{1,2} 表示匹配上一個元素至少一次,最多兩次,這里就是 \d一次或兩次

b) 200~255 正則表達式為 2((5[0-5])|([0-4]\d)),又可以分為兩部分 200~249 和 250~255

2 表示必須以2開頭

5[0-5] 表示匹配 50~55 之間的數

[0-4]\d 表示 00~49 之間的數

3.三個部分的正則匹配

a) (0~255) 的正則表達式可以寫為 (2((5[0-5])|([0-4]\d)))|([0-1]?\d{1,2})

b) .(0~255) 的正則表達式可以寫為 .((2((5[0-5])|([0-4]\d)))|([0-1]?\d{1,2}))

c) .(0~255) 匹配3次的正則表達式可以寫為 (.((2((5[0-5])|([0-4]\d)))|([0-1]?\d{1,2}))){3}

總結

原文鏈接:https://blog.csdn.net/m0_65463546/article/details/127224880

欄目分類
最近更新