IPAddress或CIDR块匹配regex

2024-04-23 13:05:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要检查任何IPv4地址或以下CIDR块之一的字符串:/16或/24。 所以,192.168.0.1应该匹配。192.168.0.0/16应该匹配。192.168.0.0/17不应匹配 我正在使用以下regex:

re.compile(r'^([0-9]{1,3}\.){3}[0-9]{1,3}(/(16|24))?')

它匹配所有IP地址,但也匹配192.168.0.0/aaaa等字符串

现在,如果我更改regex(删除?结束时):

re.compile(r'^([0-9]{1,3}\.){3}[0-9]{1,3}(/(16|24))')

它匹配CIDR块/16或/24,但不再匹配IP地址(例如192.168.0.1)。

不是'?'应该检查一个组的可选事件吗?我做错什么了?

注意:我知道IP地址regex本身并不完美,但我更感兴趣的是获得有关所述问题的帮助。


Tags: 字符串re地址事件感兴趣regexipv4cidr
3条回答

“?”的语义有点复杂。你可以把它想象成副词“可能”的同义词 它是这样工作的:如果有一个子串匹配我的模式,然后继续匹配过程。我“强调”如果因为语义上的含意说,万一前提不满足,整句话还是真的。

因此,现在让我们将这一原则应用到您的案例中。你放了一个'?'在后缀上。假设前面的部分匹配,现在,让我们来处理后缀:如果有一个后缀匹配您的模式,那么整个字符串将匹配。如果后缀不匹配,就没有问题:用“?”标记的块是“可选的”(记住“可能的”语义,或者等价地,记住隐含语义),因此字符串仍然匹配。

所以,放一个'?'模式的最后一部分中的块不是很有用,因为无论是否有匹配的后缀,字符串仍将匹配。实际上,可选块只在字符串中间才有用。

这应该有效:

^([0-9]{1,3}\.){3}[0-9]{1,3}($|/(16|24))$

它检查$行尾)或/1624

正如您所说的?将组标记为可选,这意味着如果可能的话,它将尝试将其包含在匹配中。但在某些情况下,它不能喜欢192.168.0.0/aaaa,但因为它是可选的,所以它仍然会匹配其他部分。

这就是为什么上面的regex更适合您的需要。这样,只有当它以/24/16行尾例如192.168.0.1结尾时,才能获得匹配。

精确匹配

匹配0.0.0.0255.255.255.255。如果指定了CIDR块,则仅当CIDR是1624时才匹配。In action

^                                                 # Start string
(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.               # A in A.B.C.D
(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.               # B in A.B.C.D
(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.               # C in A.B.C.D
(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)($|/(16|24))?    # D in A.B.C.D and /16 or /24
$                                                 # End string

相关问题 更多 >