Python正则表达式匹配IPV4地址无法工作

4
我正在使用re库。
def validate_ip(self, ip):
    pattern = re.compile(r'([01]?[0-9]?[0-9]|2[0-4][0-9]|2[5][0-5])\.{4}')
    matchObj = re.match(pattern, ip)

    if matchObj == None:
        print "Invalid IP:", ip
        sys.exit(0)

当我传递IP 192.0.0.0时,输出如下:
Invalid IP: 192.0.0.0

为什么不匹配?

为什么要使用正则表达式?Python自带“电池”,包括ipaddress - user1907906
1
@Tichodroma:从Python 3.3开始才支持,看起来OP正在使用Python 2。 - Martijn Pieters
@MartijnPieters 确实,print 是一个很好的标志。 - user1907906
2个回答

7
您的模式匹配一个三位数,后跟正好四个点:
>>> pattern = re.compile(r'([01]?[0-9]?[0-9]|2[0-4][0-9]|2[5][0-5])\.{4}')
>>> pattern.match('255....')
<_sre.SRE_Match object at 0x1026eda80>

{4}并不适用于其前面的所有内容,它仅适用于仅有的\.

你需要这样做:

r'(([01]?[0-9]?[0-9]|2[0-4][0-9]|2[5][0-5])\.){3}([01]?[0-9]?[0-9]|2[0-4][0-9]|2[5][0-5])'

这个模式匹配你的数字模式,加上一个.3次,因为现在{3}适用于前面分组表达式中的所有内容(使用(...))。然后你仍然需要单独匹配最后一个数字组。

演示:

>>> pattern = re.compile(r'(([01]?[0-9]?[0-9]|2[0-4][0-9]|2[5][0-5])\.){3}([01]?[0-9]?[0-9]|2[0-4][0-9]|2[5][0-5])')
>>> pattern.match('192.0.0.0')
<_sre.SRE_Match object at 0x1023bf588>

作为旁注,只需使用if not match:来测试匹配失败;在布尔上下文中,None是一个假值。即使你真的想测试None,你也应该使用if match is None:,使用身份测试。

仅供参考,此表达式并不匹配所有有效的IPv4地址。例如,它无法匹配192.168.0.01192.168.1,这两者都是192.168.0.1的有效同义词。 - Sven Marnach
@SvenMarnach:192.168.0.01实际上是匹配的。[01]?[0-9]?[0-9]部分允许最多有两个前导零。 - Martijn Pieters

2
如果您使用Python 3.3+,请使用ipaddress库。
import ipaddress

for ip in ["192.0.0.0", "0.0.0.0", "192.168.0.256"]:
    try:
        ipaddress.ip_address(ip)
        print("{} is valid".format(ip));
    except ValueError:
        print("{} is invalid".format(ip))

输出:

192.0.0.0 is valid
0.0.0.0 is valid
192.168.0.256 is invalid

1
ipaddress 在 Python 3.3 中是新功能;根据 print 语句,OP 正在使用 Python 2。 - Martijn Pieters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接