正则表达式只匹配PUBLIC IPv4地址

时间:2015-10-31 15:07:45

标签: regex

起初,我认为很容易找到只匹配互联网上公共IPv4地址的正则表达式。然而,经过大量的谷歌搜索,我什么都没有,所以我尝试 编写正则表达式,如下(Perl风味),

[0-9]\.(?:[0-9]{1,3}\.){2}[0-9]{1,3}|
1[1-9]\.(?:[0-9]{1,3}\.){2}[0-9]{1,3}|
[2-9][0-9]\.(?:[0-9]{1,3}\.){2}[0-9]{1,3}|
1[0-6][0-9]\.(?:[0-9]{1,3}\.){2}[0-9]{1,3}|
17[0-1]\.(?:[0-9]{1,3}\.){2}[0-9]{1,3}|
172\.0\.(?:[0-9]{1,3}\.)[0-9]{1,3}|
172\.1[0-5]\.(?:[0-9]{1,3}\.)[0-9]{1,3}|
(172\.3[2-9]\.)(?:[0-9]{1,3}\.)[0-9]{1,3}|
(172\.[4-9][0-9]\.)(?:[0-9]{1,3}\.)[0-9]{1,3}|
...

正则表达式似乎不准确且效率低下,有人有更好的方法来编写正则表达式吗?

5 个答案:

答案 0 :(得分:4)

我更愿意捕获每个八位字节并检查子网是否在代码中是私有的而不是正则表达式。但是,我对你的问题很感兴趣。

根据Wikipedia,有3个私有IP地址范围。

>>> from Levenshtein import distance
>>> distance("compare", "clompare")
1
>>> distance("compare", "compaer")
2

现在假设您没有像10.0.0.0 - 10.255.255.255 172.16.0.0 - 172.31.255.255 192.168.0.0 - 192.168.255.255 那样疯狂的类似IP的字符串,您可以使用负面的lookbehind来做你想做的事情:

55.300.666.1

让我们再看一遍,为了清晰起见,添加了一些换行符:

(\d+)(?<!10)\.(\d+)(?<!192\.168)(?<!172\.(1[6-9]|2\d|3[0-1]))\.(\d+)\.(\d+)

第一行检查第一个八位字节不是(\d+)(?<!10) \.(\d+)(?<!192\.168)(?<!172\.(1[6-9]|2\d|3[0-1])) \.(\d+)\.(\d+) 。第二行检查前两个八位字节不是10还是192.168172.16之间。第三行没什么特别的。 Regex101

PS:我知道172.31是localhost,但我不知道它是否是私有的(我不是网络工程师)。您可能需要根据需要进行即兴创作。

答案 1 :(得分:4)

试试这个:

^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(?<!172\.(16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31))(?<!127)(?<!^10)(?<!^0)\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(?<!192\.168)(?<!172\.(16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31))\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(?<!\.255$)$

正确不匹配此无效的ips:

999.999.999.999.
108.0.0.01
0.1.2.3
00.0000.00.00
192.168.l.1
912.456.123.123
.3.3.3.0
192.168.o.0

本地IP不匹配:

172.16.0.9
172.16.4.1
172.17.1.1
127.0.0.2
10.0.1.5
10.0.0.1
10.155.155.155
10.255.255.254
172.16.0.4
172.16.0.1
172.17.1.1
172.31.254.254
192.168.1.2
192.168.254.0

最后广播IP不匹配:

60.123.247.255
196.168.255.255
10.255.255.255
192.168.255.255

几乎每个我测试过的IP都匹配。不能说我真的做了很多测试,所以欢迎提出建议

答案 2 :(得分:1)

 ^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(?<!172\.(16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31))(?<!127)(?<!^10)(?<!^0)\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(?<!192\.168)(?<!172\.(16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31))\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(?<!\.255$)(?<!\b255.255.255.0\b)(?<!\b255.255.255.242\b)$

一种略有不同的解决方案,如果您通过防火墙配置进行grep删除,则会删除错误的肯定地址。删除通用掩码255.255.255.0和255.255.255.242。根据需要添加和删除。

答案 3 :(得分:0)

如果您希望验证纯粹的公共IPv4地址,我们可以删除所有Reserved IPv4 addresses,如下所示:

  • 0.0.0.0/8:当前网络
  • 10.0.0.0/8:专用网络
  • 100.64.0.0/10:共享地址空间
  • 127.0.0.0/8:Loopback
  • 169.254.0.0/16:Link-local
  • 172.16.0.0/12:专用网络
  • 192.0.0.0/24:IETF协议分配
  • 192.0.2.0/24:TEST-NET-1,文档和示例
  • 192.88.99.0/24:IPv6到IPv4中继(包括2002 :: / 16)
  • 192.168.0.0/16:专用网络
  • 198.18.0.0/15:网络基准测试
  • 198.51.100.0/24:TEST-NET-2,文档和示例
  • 203.0.113.0/24:TEST-NET-3,文档和示例
  • 224.0.0.0/4:IP多播(以前的D类网络)
  • 240.0.0.0/4:保留(以前的E类网络)
  • 255.255.255.255:广播

(摘自Wikipedia

这可以放在一个简单的正则表达式中,不使用lookbehinds(因此,正则表达式可以在JavaScript中使用):

(^0\.)|(^10\.)|(^100\.6[4-9]\.)|(^100\.[7-9]\d\.)|(^100\.1[0-1]\d\.)|(^100\.12[0-7]\.)|(^127\.)|(^169\.254\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^192\.0\.0\.)|(^192\.0\.2\.)|(^192\.88\.99\.)|(^192\.168\.)|(^198\.1[8-9]\.)|(^198\.51\.100\.)|(^203.0\.113\.)|(^22[4-9]\.)|(^23[0-9]\.)|(^24[0-9]\.)|(^25[0-5]\.)

同样,这假设您已经事先验证过它实际上是一个有效的IPv4地址。

答案 4 :(得分:0)

Anubioz的+ Irvin Lim =

^(?!^0\.)(?!^10\.)(?!^100\.6[4-9]\.)(?!^100\.[7-9]\d\.)(?!^100\.1[0-1]\d\.)(?!^100\.12[0-7]\.)(?!^127\.)(?!^169\.254\.)(?!^172\.1[6-9]\.)(?!^172\.2[0-9]\.)(?!^172\.3[0-1]\.)(?!^192\.0\.0\.)(?!^192\.0\.2\.)(?!^192\.88\.99\.)(?!^192\.168\.)(?!^198\.1[8-9]\.)(?!^198\.51\.100\.)(?!^203.0\.113\.)(?!^22[4-9]\.)(?!^23[0-9]\.)(?!^24[0-9]\.)(?!^25[0-5]\.)(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))$

https://i.stack.imgur.com/vWtlj.png

(不广播)