python3字符串正则匹配多个ipv4

python3字符串正则匹配多个ipv4

在python中使用正则表达式需要import re模块。
Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式。

构造ip匹配规则:
.做分割,每个字段允许范围为0~255。
在这里插入图片描述
(0、1、2、为百位)
根据分割图,可先将0~255分为两部分:0~199、200~255。
在这里插入图片描述
根据分割图2,可将200~255分为200~249、250~255。200~249可表示为当百位为2且个位为0~4时,个位可为0~9;250~255可表示为当百位为2且十位为5时,个位为0~5
又根据ip的特征,前三个字段后面跟着符号.,所以ip地址(假设为127.0.0.1)可分为127.0.0.0
综上构造正则表达式
0~199可表示为当百位为0或1时,个位与百位可为0~9
200~249可表示为当百位为2且个位为0~4时,个位可为0~9
250~255可表示为当百位为2且十位为5时,个位为0~5
则0~255的正则表达式为[01]?\d?\d|2[0-4]\d|25[0-5]
ip匹配正则表达式为

(([01]?\d?\d|2[0-4]\d|25[0-5])\.){3}([01]?\d?\d|2[0-4]\d|25[0-5])

re模块匹配函数选择(各函数使用方法详见菜鸟教程)
re.compile(pattern[, flags]):编译正则表达式,生成一个正则表达式( Pattern )对象,供其他匹配函数调用,使用此正则表达式。
re.match(pattern, string, flags=0):只能匹配第一个ip值(共1个值),且只要字符串第一个字符匹配不成功,match()就返回none。
re.search(pattern, string, flags=0):只能匹配第一个ip值(共1个值),与match()不同的是,可以在字符串任意位置匹配成功,返回第一个匹配成功的值。
re.findall(string[, pos[, endpos]]):匹配所有ip值,返回一个list。
re.finditer(pattern, string, flags=0):匹配所有ip值,并把它们作为一个迭代器返回。

据上述,我选择findall()与finditer()函数,主要以findall()为例。
findall():
在使用此函数时,若在正则表达式中使用了(),需注意:
使用()时,findall函数只返回最边上()里匹配的值,但是外面会作为规则匹配。且会根据()由外向内、从左至右分别将每个()里匹配成功的字符串做为返回的list里的一个元组值。
这么说可能很难明白,看实例:python3-findall()实测
先看例1:

import re
str = "127.0.0.1 a1.12.123.249 b256.2.2.2 c3.3.3.555 d1122.4.4.4 e5.5.5.1122 f127.0.0.1"
pi = re.compile(r'((([01]?\d?\d|2[0-4]\d|25[0-5])\.){3}([01]?\d?\d|2[0-4]\d|25[0-5]))');
result2 = pi.findall(str);
for i in result2:
    print (i[0]);

返回结果:

127.0.0.1
1.12.123.24
56.2.2.2
3.3.3.55
122.4.4.4
5.5.5.112
127.0.0.1

虽然匹配的结果都是正确的ip,但是很多时候,我们并不希望将3.3.3.555匹配成3.3.3.55,也不希望1122.4.4.4匹配成122.4.4.4。这可以通过\D(非数字的字符)来排除,只有ip地址前后匹配不是数字才返回。\D位于()外,仅作为匹配规则。
例2:

import re
str = "127.0.0.1 a1.12.123.249 b256.2.2.2 c3.3.3.555 d1122.4.4.4 e5.5.5.1122 f127.0.0.1"
pi = re.compile(r'\D((([01]?\d?\d|2[0-4]\d|25[0-5])\.){3}([01]?\d?\d|2[0-4]\d|25[0-5]))\D');
result2 = pi.findall(str);
for i in result2:
    print (i[0]);

输出结果:

1.12.123.249

a1.2.123.249 b仅匹配输出1.12.123.249,并没有将\D匹配的a空格输出。\D位于()外,仅作为匹配规则,不将匹配的字符输出。
但这里有个问题,127.0.0.1没匹配到,原因是127.0.0.1后面没有字符。这里存在IP地址在字符串第一个字符或最后一个字符匹配成功的问题,需要用^$匹配。(注:代码量就增多了,如果你有好的方法,欢迎评论交流。)
例3:

import re
result_list = [];
str = "127.0.0.1 a1.12.123.249 b256.2.2.2 c3.3.3.555 d1122.4.4.4 e5.5.5.1122 f127.0.0.1"
#头
pi2 = re.compile(r'^((([01]?\d?\d|2[0-4]\d|25[0-5])\.){3}([01]?\d?\d|2[0-4]\d|25[0-5]))\D');
result3 = pi2.findall(str);
for i in result3:
    result_list.append(i[0]);
    # print (i[0]);
#中
pi = re.compile(r'\D((([01]?\d?\d|2[0-4]\d|25[0-5])\.){3}([01]?\d?\d|2[0-4]\d|25[0-5]))\D');
result2 = pi.findall(str);
for i in result2:
    result_list.append(i[0]);
    # print (i[0]);
#尾
pi3 = re.compile(r'\D((([01]?\d?\d|2[0-4]\d|25[0-5])\.){3}([01]?\d?\d|2[0-4]\d|25[0-5]))$');
result4 = pi3.findall(str);
for i in result4:
    result_list.append(i[0]);
    # print (i[0]);

print(result_list);

输出结果:

['127.0.0.1', '1.12.123.249', '127.0.0.1']

finditer():
没有findall()()外的仅作匹配规则这一特性
例4:

import re
result_list = [];
str = "127.0.0.1 a1.12.123.249 b256.2.2.2 c3.3.3.555 d1122.4.4.4 e5.5.5.1122 f127.0.0.1"
#头
pi2 = re.compile(r'^((([01]?\d?\d|2[0-4]\d|25[0-5])\.){3}([01]?\d?\d|2[0-4]\d|25[0-5]))\D');
result3 = pi2.finditer(str);
for i in result3:
    result_list.append(i.group());
    # print (i[0]);
#中
pi = re.compile(r'\D((([01]?\d?\d|2[0-4]\d|25[0-5])\.){3}([01]?\d?\d|2[0-4]\d|25[0-5]))\D');
result2 = pi.finditer(str);
for i in result2:
    result_list.append(i.group());
    # print (i[0]);
#尾
pi3 = re.compile(r'\D((([01]?\d?\d|2[0-4]\d|25[0-5])\.){3}([01]?\d?\d|2[0-4]\d|25[0-5]))$');
result4 = pi3.finditer(str);
for i in result4:
    result_list.append(i.group());
    # print (i[0]);

print(result_list);

#finall_list=[];
#for i in result_list:
#    finall_list.append(re.sub(r'[^\d.]','',i));
#print(finall_list);

输出结果:

['127.0.0.1 ', 'a1.12.123.249 ', 'f127.0.0.1']
#加上上述代码#号部分,新增输出['127.0.0.1 ', '1.12.123.249 ', '127.0.0.1']

例5:

import re
result_list = [];
str = "127.0.0.1 a1.12.123.249 b256.2.2.2 c3.3.3.555 d1122.4.4.4 e5.5.5.1122 f127.0.0.1"

pi = re.compile(r'((([01]?\d?\d|2[0-4]\d|25[0-5])\.){3}([01]?\d?\d|2[0-4]\d|25[0-5]))');
result2 = pi.finditer(str);
for i in result2:
    result_list.append(i.group());
    # print (i[0]);
print(result_list);

输出结果:

['127.0.0.1', '1.12.123.24', '56.2.2.2', '3.3.3.55', '122.4.4.4', '5.5.5.112', '127.0.0.1']

例4 中使用了\Dfinditer()\D进行匹配并输出(a1.12.123.249和f127.0.0.1);例5与例1效果相同,可以根据实际情况使用。

还是太年轻,时隔许久再来看自己的文章,发现自己看得都云里雾里了。已加以修改,若还有不明处,评论私信都可以,谢谢大家能看到这里。
(注:本人菜鸡,个人见解,如有错误,欢迎评论指出)

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值