【python】使用正则在不规则字符串中提取出多个ip地址
在不规则字符串中提取ip地址
- 一、ip地址正则表达式
- 二、提取ip
- ip地址提取中可能出现的错误
- ip地址提取思路
- 三、完整代码
ipv4地址总长度为32位,共4段,每段8位,以‘.’分割,每段为0~255的十进制数字
一、ip地址正则表达式
分段正则:
| 取值区间 | 正则 | 合并整理 |
|---|---|---|
| 0-9 | \d | |
| 10-99 | \d{2} | [1-9]?\d |
| 100-199 | 1\d{2} | 1\d{2} |
| 200-249 | 2[0-4]\d | 2[0-4]\d |
| 250-255 | 25[0-5] | 25[0-5] |
合并整理:
# 每一段的正则:
(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)# 完整ip的正则:
r'((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)'
二、提取ip
示例字符串:
str = "123.12.12.12q we1764.12.12.76asd12.12.23.287frg45.23.278.34hrdf127.0.0.1jj255.45.45.45bghtbh43.0.76.345"
# 以上能够构成ip地址的有 ['127.0.0.1', '255.45.45.45', '123.12.12.12']
ip地址提取中可能出现的错误
- 第一段或第四段位数超出,在匹配时直接舍去
- 十进制数大于255,超出ip范围,在匹配时舍去第一位或最后一位而去两位使数字保持在范围内
- findall匹配中间部分时需要将捕获组转化为非捕获组
ip地址提取思路
在从字符串中提取ip时可以将其分为开头,中间和结尾三部分:
- 中间部分
判断可能符合ip地址格式的字符串部分的前后均需要至少一位非数字字符来截取。
ip地址部分前三位只匹配数字长度为1~3位,第四段则使用ip地址的正则表达式进行匹配,避免出现第四段为大于255以上的数字时,在最终提取ip时舍去最后一位而匹配成功的情况。
最后将分组加上非捕获符号后,使用findall匹配出中间所有符合ip地址格式的字符串,返回ip地址列表,正则表达式如下:
r'\D(?:\d{1,3}\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\D'
- 开头
和中间部分作为区分,开头为ip地址时,符合ip格式的字符串之前不存在其他字符,因此使用match从头开始匹配,ip地址第四段段之后要求至少有一个非数字字符,匹配成功则将提取的字符串添加到ip地址列表中,正则表达式如下
r'(\d{1,3}\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\D'
- 结尾
结尾的问题在于ip地址后不存在其他字符,因此在第四段匹配后加结束符来判断终止,避免出现第四段为大于255以上的数字时舍去最后一位而匹配成功的情况,匹配成功则将提取的字符串添加到ip地址列表中,正则表达式如下:
r'\D(\d{1,3}\.){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)$'
三、完整代码
import re# 输入要匹配的字符串
# str = input('ip:')# 测试用字符串
# str = "fsff123.12.12.12q we1764.12.12.76asd12.12.23.287frg45.23.278.34hrdf127.0.0.1jj255.45.45.45bghtbh43.0.76.345"
str = "123.12.12.12q we1764.12.12.76asd12.12.23.287frg45.23.278.34hrdf127.0.0.1jj255.45.45.45bghtbh43.0.76.345"# 分为开头,中间和结尾三部分,提取可能包含ip地址的字符串
# 匹配中间部分的ip,返回列表
result = re.findall(r'\D(?:\d{1,3}\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\D',str)
print(result)# 匹配开头可能出现ip
ret_start = re.match(r'(\d{1,3}\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\D',str)
if ret_start:print("start:",ret_start.group())result.append(ret_start.group())# 匹配结尾
ret_end = re.search(r'\D(\d{1,3}\.){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)$',str)
if ret_end:print("end: ",ret_end.group())result.append(ret_end.group())print('*'*20)
print("result: ",result) #result: ['g45.23.278.34h', 'f127.0.0.1j', 'j255.45.45.45b', '123.12.12.12']# 构造列表保存ip地址
ip_list = []
for r in result:# 正则提取ipret = re.search(r'((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)', r)if ret:# 匹配成功则将ip地址添加到列表中ip_list.append(ret.group())# 输入结果列表
print(ip_list) # ['127.0.0.1', '255.45.45.45', '123.12.12.12']
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
