我需要检查任何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本身并不完美,但我更感兴趣的是获得有关所述问题的帮助。
“?”的语义有点复杂。你可以把它想象成副词“可能”的同义词 它是这样工作的:如果有一个子串匹配我的模式,然后继续匹配过程。我“强调”如果因为语义上的含意说,万一前提不满足,整句话还是真的。
因此,现在让我们将这一原则应用到您的案例中。你放了一个'?'在后缀上。假设前面的部分匹配,现在,让我们来处理后缀:如果有一个后缀匹配您的模式,那么整个字符串将匹配。如果后缀不匹配,就没有问题:用“?”标记的块是“可选的”(记住“可能的”语义,或者等价地,记住隐含语义),因此字符串仍然匹配。
所以,放一个'?'模式的最后一部分中的块不是很有用,因为无论是否有匹配的后缀,字符串仍将匹配。实际上,可选块只在字符串中间才有用。
这应该有效:
它检查
$
(行尾)或/
和16
或24
。正如您所说的
?
将组标记为可选,这意味着如果可能的话,它将尝试将其包含在匹配中。但在某些情况下,它不能喜欢192.168.0.0/aaaa
,但因为它是可选的,所以它仍然会匹配其他部分。这就是为什么上面的regex更适合您的需要。这样,只有当它以
/24
、/16
或行尾例如192.168.0.1
结尾时,才能获得匹配。精确匹配
匹配
0.0.0.0
到255.255.255.255
。如果指定了CIDR块,则仅当CIDR是16
或24
时才匹配。In action:相关问题 更多 >
编程相关推荐