這次帶給大家正規匹配IP的圖文詳解,正規符合IP的注意事項有哪些,下面就是實戰案例,一起來看一下。
這裡給大家詳細講解一下一個符合IP位址的正規表示式,
有關正則方面的知識,會在詳細的講解中提到。
在講解之前,我先跟大家介紹一下,ip位址的生成規則。
IP位址,是由32位元數字二進位轉為四個十進位的字串組成。
怎麼轉化?以下說明:
二進位:11111111111111111111111111111111
11111111111111111111
1111111111111111111
11 轉換:2^7+2^6+2^5+2^4+ 2^3+2^2+2^1+2^0=255
轉為十進位範圍:0~255.0~255.0~255.0~255
## # 這是位址的範圍。 依照這個產生IP的規則和範圍,我們可以用正規表示式來配對出IP位址,但要怎麼符合呢?各人有各人的方法,這裡我講解一下我的思路。 依照IP位址的字串規律,我把符合IP位址的運算式分成兩個部分來考慮。 第一部分:符合30~255.(注意後面的一點) 第二部分:配對最後的數字0~255 先匹配出0~255.(注意後面的點) 這個字串,然後重複匹配3次,然後再匹配最後的數字部分0~255。這就是我匹配IP位址的思路。首先,我要提一下,正規是沒有辦法做數字運算的,所以,我們無法用數字運算的方式篩選出IP的數字範圍。既然沒法用數字運算的方式篩選出IP的數字範圍,那麼我們該用什麼其他方式來篩選這個數字範圍呢?我的想法是分組
討論,然後再把這些分組合併起來組成IP的數字範圍。 ①、假設IP的數字是百位數,那麼依照IP的數位範圍,我們可以得到以下幾種情況。假設第一個數字為1,那麼這個數字的範圍就為1[0-9][0-9]。這個應該不難理解,就不解釋。 ②、假設第一個數字為2,那麼依照IP數字的範圍規則,這裡又要分成兩種情況,為什麼?你想想,最大數字是255,當十位數為5時,個位數最大隻能為5是吧?而當十位數為0到4時,個位數可以是任意數字對吧? 所以,這裡的兩種情況分別是: A、2[0-4][0-9] A、2[0-4][0-9]## ③、分析完了百位數的情況,接下來就是十位數的情況了,假如是十位數,那麼十位數的前面第一個數不能為零是吧?
所以十位數的情況可以是:[1-9][0-9]
④、剩下的就是個位數的情況了,個位數的情況,大家應該很容易下結論,就是:[0-9]。
四種情況分析下來,我們得到了IP數字的範圍分組為:
1[0-9][0-9]# ## 1[0-9][0-9]# -2 4][0-9]
25[0-5]
9][0-
# 怎麼把上面的分組用正規表示式表示出來呢?很簡單,用正規的或符號|和分組符號()就可以了,所以上面的分組正規表示式為:(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])|([1-9][0-9])|([0-9])
寫到這裡,數字的匹配範圍正則表達式已經寫好了,那麼根據我前面的思路: 第一部分:匹配3個0~255.(注意後面的一個點)
第二部分:搭配最後的數字0~255
我們來符合IP位址的第一部分,正規表示式如下:
(1[0-9][0-9]\.)|(2[0-4][0-9]\.)|(25[0-5]\.)|([1-9][0-9]\.)|([0-9]\.)
我在每個數字的後面加了一個點就是配對出0~255.(注意後面的一點)
那麼要先重複配對三次呢?很簡單,我們只要把這五個分組當成整體,再重複匹配三次就行了,正則表達式如下:
((1[0-9][0-9]\.)|(2[0-4][0-9]\.)|(25[0-5]\.)|([1-9][0-9]\.)|([0-9])\.)){3}
第一部分已經匹配出來了,接下來就是拼接上第二部分的數字了,數字部分上面已經寫得很清楚了,就不再解釋了,下面是完整的正則表達式:
((1[0-9][0-9]\.)|(2[0-4][0-9]\.)|(25[0-5]\.)|([1-9][0-9]\.)|([0-9]\.)){3}((1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])|([1-9][0-9])|([0-9]))
寫到這裡,正則匹配IP的表達式已經出來了,不過,這並不是最終的匹配IP的正規表示式,為什麼呢?很簡單,正規表示式會對每一個分組都進行捕獲匹配,上面把匹配IP分成了那麼多分組,而每一個分組的內容都會被正則所捕獲,那上面不知道已經捕獲多少IP了,呵呵,那要怎麼去掉分組的內容呢?很簡單,用這個符號?:
?:符號放在()圓括號裡面,是捕獲分組,但不捕獲正則表達式的內容的意思。那麼,我們把它放到每一個分組裡面去,不就去掉了分組的內容了嗎?所以,我們還要給每個分組加上?:,加上後正則如下:
(?:(?:1[0-9][0-9]\.)|(?:2[0-4][0-9]\.)|(?:25[0-5]\.)|(?:[1-9][0-9]\.)|(?:[0-9]\.)){3}(?:(?:1[0-9][0-9])|(?:2[0-4][0-9])|(?:25[0-5])|(?:[1-9][0-9])|(?:[0-9]))
即使到這裡,還是沒有把IP地址匹配出來,我們還要用^和$來限製字符串的開頭與結尾,所以,最後的符合IP位址的正規表示式是:
^(?:(?:1[0-9][0-9]\.)|(?:2[0-4][0-9]\.)|(?:25[0-5]\.)|(?:[1-9][0-9]\.)|(?:[0-9]\.)){3}(?:(?:1[0-9][0-9])|(?:2[0-4][0-9])|(?:25[0-5])|(?:[1-9][0-9])|(?:[0-9]))$
這就是我符合IP位址最完整的正規表示式,大家可以參考一下,有什麼bug也望讀者提出,免得誤導其他讀者。
上面的正規表示式的()括號都是成對出現的,假如有不成對出現,請讀者自己加一下,可能是我漏寫了。
以下是我的測試:
<?php $pattern = '/^(?:(?:2[0-4][0-9]\.)|(?:25[0-5]\.)|(?:1[0-9][0-9]\.)|(?:[1-9][0-9]\.)|(?:[0-9]\.)){3}(?:(?:2[0-5][0-5])|(?:25[0-5])|(?:1[0-9][0-9])|(?:[1-9][0-9])|(?:[0-9]))$/'; //正则匹配ip地址 $ip = '254.21.0.198'; preg_match($pattern,$ip,$out); echo '<pre class="brush:php;toolbar:false">'; print_r($out); $ip = '255.777.0.198'; preg_match($pattern,$ip,$out); print_r($out); $ip = '07.25.8.198'; preg_match($pattern,$ip,$out); print_r($out); $ip = '1207.25.8.198'; preg_match($pattern,$ip,$out); print_r($out); $ip = 'qq107.25.8.198'; preg_match($pattern,$ip,$out); print_r($out); $ip = '\.\.\.107.25.8.198'; preg_match($pattern,$ip,$out); print_r($out); $ip = '\.\.\. 7.25.8.198'; preg_match($pattern,$ip,$out); print_r($out); $ip = '107.25.8.19822vvv'; preg_match($pattern,$ip,$out); print_r($out); $ip = '107.25.r8.1982'; preg_match($pattern,$ip,$out); print_r($out); $ip = '107.225.8.19'; preg_match($pattern,$ip,$out); print_r($out); $ip = '225.225.225.225'; preg_match($pattern,$ip,$out); print_r($out); $ip = '0.0.0.0'; preg_match($pattern,$ip,$out); print_r($out); $ip = '00.0.0.0'; preg_match($pattern,$ip,$out); print_r($out); $ip = '0.202.1.0'; preg_match($pattern,$ip,$out); print_r($out); $ip = '0.202.1.226'; preg_match($pattern,$ip,$out); print_r($out); $ip = '249.202.1.0'; preg_match($pattern,$ip,$out); print_r($out); $s=''; for($i=0;$i<32;$i++){ $s .= '1'; } echo $s; echo strlen($s);
相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!
推薦閱讀:
以上是正規匹配IP的圖文詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!