python如何利用re模塊正則表達式匹配ip地址
python中利用正則表達式判斷ipv4地址是否合法
ip地址的范圍為0.0.0.0-255.255.255.255,分成四段,則每段的范圍都是0-255,因此,以一段進行分析:
在進行書寫匹配規(guī)則時,可以將每段的取值分為4個區(qū)間。即0-99、100-199、200-249、250-255。
其正則匹配的表達式應為:
# 匹配 0-255的表達式書寫方法pattern = re.compile(r'([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])') # 匹配 0-255的表達式書寫方法 pattern = re.compile(r'([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])')
以下作具體解釋
- 0-99:[1-9]?\d
問號(?)表示匹配0或1次,此表達式可以匹配0-99內任意是數(shù)值。
- 100-199:1\d\d
第一位為1,第二位和第三位為0-9之間的任意數(shù)值。
- 200-249:2[0-4]\d
200-249范圍內,第一位固定為2,第二位取值范圍為[0-4],第三位為0-9之間任意數(shù)字,使用’\d’進行匹配。
- 250-255:25[0-5]
250-255范圍內,前兩位固定為25,最后一位取值為[0-5]。
使用 | 符號,將四部分連接起來,即是一條完整的匹配0-255范圍的表達式:([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])
此時應該已經能夠理解,如何進行一段ip地址的匹配,再講解如何匹配完整的ip地址。
簡單理解就是(0-255).(0-255).(0-255).(0-255)。使用四段相同的表達式,并在四段表達式之間增加3個點(.)。
可將前三段ip值和三個點看作三部分,即每部分為(0-255).。
(0-255).的匹配表達式可書寫為(([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.),此表達式需要使用三次,因此可以寫成 (([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.){3}
最終,匹配0.0.0.0-255.255.255.255的表達式如下所示:
# 匹配 0.0.0.0-255.255.255.255的表達式書寫方法
pattern = re.compile(r'(([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.){3}([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])')下面作幾個測試用例(使用fullmatch)
In [1]: pattern.fullmatch('0.123.12.23')
Out[1]: <re.Match object; span=(0, 11), match='0.123.12.23'>
In [2]: pattern.fullmatch('192.168.0.1')
Out[2]: <re.Match object; span=(0, 11), match='192.168.0.1'>
In [3]: pattern.fullmatch('255.255.255.255')
Out[3]: <re.Match object; span=(0, 15), match='255.255.255.255'>
# 以上三個ip都屬于正常ip,因此能夠正確匹配
# -----------------------------------------------
# 以下兩個示例不是正確的ip,所以匹配不到,無輸出結果
In [4]: pattern.fullmatch('255.255.255.256')
In [5]: pattern.fullmatch('1255.255.255.255')再使用search、match方法對以上兩個錯誤ip進行匹配測試。
In [11]: pattern.search('255.255.255.256')
Out[11]: <re.Match object; span=(0, 14), match='255.255.255.25'>
# 匹配結果為 255.255.255.25
In [12]: pattern.search('1255.255.255.255')
Out[12]: <re.Match object; span=(1, 15), match='255.255.255.25'>
# 匹配結果為 255.255.255.25
In [13]: pattern.match('255.255.255.256')
Out[13]: <re.Match object; span=(0, 14), match='255.255.255.25'>
# 匹配結果為 255.255.255.25
In [14]: pattern.match('1255.255.255.255')
# 無輸出結果
# -----------------------------------
# 請注意觀察以下示例的匹配結果
In [15]: pattern.search('257.127.0.0.1')
Out[15]: <re.Match object; span=(1, 11), match='57.127.0.0'>
In [16]: pattern.search('255.255.255.122.256')
Out[16]: <re.Match object; span=(0, 15), match='255.255.255.122'>為何會出現(xiàn)上述結果?首先對于search、match、fullmatch進行一個對比:
| 方法 | 解釋 |
|---|---|
| search | 只匹配一次,查找整個字符串 |
| match | 只匹配一次,從開頭開始匹配 |
| fullmatch | 對字符串進行完整匹配 |
由于search匹配時,會查找整個字符串,然后返回滿足表達式的結果。
所以使用search方法進行匹配時,對于ip的第一個字段和最后一個字段出錯的情況下,會自動進行ip址的截取,盡量使結果滿足表達式的要求,但是這種結果并不是我們想要的。
match是從頭開始匹配,當ip地址的前三段都正確,而最后一個字段出錯時,也無法得出預期的結果。fullmatch是完全匹配,因此字符串要完全滿足ip地址規(guī)則時,才會返回正確結果,ip地址有誤時,無輸出(輸出為None)。
當然,非要使用search和match進行匹配也是可以的,首先了解一下“零寬斷言”。
零寬斷言
用于查找特定內容之前或之后的內容,但并不包括特定內容本身(零寬)。
類似于^、 $、 \b一樣的作用,指定某一位置需要滿足某些條件(斷言)。
| 表達式 | 說明 |
|---|---|
| (?=exp) | 匹配exp前面的位置 (此位置后面是exp) |
| (?<=exp) | 匹配exp后面的位置(此位置前面是exp) |
| (?!exp) | 此位置后面不能是exp |
| (?<!exp) | 此位置前面不能是exp |
匹配ip地址時,不允許對不合法的地址進行截取 以得到符合規(guī)則的ip地址,即是要求:匹配結果在原字符串中的位置之前和之后不能有被截取的點(.)和數(shù)字。

根據(jù)以上分析 修改原有正則表達式,在原表達式的前面添加(?<![\.\d]),最后面添加(?![\.\d]),即修改之后完整的表達式為:
pattern = re.compile(r'(?<![\.\d])(([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.){3}([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])(?![\.\d])')通過上面這條正則表達式,對之前錯誤的ip地址重新進行匹配驗證,
結果如下:
In [1]: import re
In [2]: pattern = re.compile(r'(?<![\.\d])(([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.){3}([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])(?![\.\d])')
# 以下各語句執(zhí)行后都無輸出結果,說明正則匹配不成功,ip地址不合法
In [11]: pattern.search('255.255.255.256')
In [12]: pattern.search('1255.255.255.255')
In [13]: pattern.match('255.255.255.256')
In [14]: pattern.match('1255.255.255.255')
In [15]: pattern.search('257.127.0.0.1')
In [16]: pattern.search('255.255.255.122.256')總結
以上就是在python中如何利用re模塊判斷ip地址是否合法的介紹。
僅為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
淺談keras中自定義二分類任務評價指標metrics的方法以及代碼
這篇文章主要介紹了淺談keras中自定義二分類任務評價指標metrics的方法以及代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06
Python HTMLParser模塊解析html獲取url實例
這篇文章主要介紹了Python HTMLParser模塊解析html獲取url實例,HTMLParser是python用來解析html的模塊,HTMLParser采用的是一種事件驅動的模式,需要的朋友可以參考下2015-04-04

