匹配 IP 地址

IPv4

要匹配 IPv4 地址格式,你需要检查数字 [0-9]{1,3} 三次 {3} 由句子\. 分隔并以另一个号码结尾。

^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$

这个正则表达式太简单 - 如果你想要它准确,你需要检查数字是在 0255 之间,正则表达式在上面接受任何位置的 444。你想要使用 25[0-5] 或任何其他 200 值 2[0-4][0-9] 或任何 100 或更少值的 [01]?[0-9][0-9] 来检查 250-255。你想检查一下\. 然后是三次 {3} 然后一次没有一段时间。

^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$

IPv6

IPv6 地址采用以冒号(:)字符分隔的 8 个 16 位十六进制字的形式。在这种情况下,我们检查 7 个单词后跟冒号,然后检查不是冒号。如果一个单词具有前导零,则它们可能被截断,这意味着每个单词可能包含 1 到 4 个十六进制数字。

^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$

然而,这是不够的。由于 IPv6 地址可能变得非常罗嗦,因此该标准规定只有零字可以被::取代。这可能只在地址中进行一次(对于 1 到 7 个连续单词之间的任何地方),否则它将是不确定的。这产生了许多(相当讨厌的)变化:

^::(?:[0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4}$
^[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,5}[0-9a-fA-F]{1,4}$
^[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,4}[0-9a-fA-F]{1,4}$
^(?:[0-9a-fA-F]{1,4}:){0,2}[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,3}[0-9a-fA-F]{1,4}$
^(?:[0-9a-fA-F]{1,4}:){0,3}[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,2}[0-9a-fA-F]{1,4}$
^(?:[0-9a-fA-F]{1,4}:){0,4}[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:)?[0-9a-fA-F]{1,4}$
^(?:[0-9a-fA-F]{1,4}:){0,5}[0-9a-fA-F]{1,4}::[0-9a-fA-F]{1,4}$
^(?:[0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4}::$

现在,把它们放在一起(使用交替)产生:

^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$|
^::(?:[0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4}$|
^[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,5}[0-9a-fA-F]{1,4}$|
^[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,4}[0-9a-fA-F]{1,4}$|
^(?:[0-9a-fA-F]{1,4}:){0,2}[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,3}[0-9a-fA-F]{1,4}$|
^(?:[0-9a-fA-F]{1,4}:){0,3}[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,2}[0-9a-fA-F]{1,4}$|
^(?:[0-9a-fA-F]{1,4}:){0,4}[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:)?[0-9a-fA-F]{1,4}$|
^(?:[0-9a-fA-F]{1,4}:){0,5}[0-9a-fA-F]{1,4}::[0-9a-fA-F]{1,4}$|
^(?:[0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4}::$

一定要以多行模式写出来并附上一堆评论,这样任何人都不可避免地要弄清楚这意味着什么并不是在你用一个钝器之后。