如何用正则表达式匹配出如下代码中的IP地址跟IP地址归属地?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何用正则表达式匹配出如下代码中的IP地址跟IP地址归属地?相关的知识,希望对你有一定的参考价值。

源代码如下:

<div class="mt8">

<p>您的IP是:<strong style='color:#ff0000'>

223.150.33.130
</strong></br>您所在的地址是:<strong style='color:#ff0000'>IANA保留地址 CZ88.NET</strong></p>
</div>

参考技术A IP (?<=您的IP是:<strong.+>\s*)(?<ip>([0-9]1,3\.)3[0-9]1,3)(?=\s*</strong>)
地址 (?<=您所在的地址是:<strong.+>\s*)(?<address>[^<]*)(?=\s*</strong>)

如果是用一个正则的话
(?n)(?<=您的IP是:<strong.+>\s*)(?<ip>([0-9]1,3\.)3[0-9]1,3)\s*</strong></br>您所在的地址是:<strong.+>\s*(?<address>[^<]*)(?=\s*</strong>)

提取出两个捕获体分别对应IP和地址

有问题的话楼主请追问
参考技术B

您的IP是:<[^>]*?>(?<ip>[^<]*)</strong></br>您所在的地址是:<[^>]*?>(?<address>[^<]*?)</strong></p>

追问

能加个好友吗?还有几个正则表达式的问题想请教~另外,你这个是什么工具啊?

追答

regex match tracer

追问

不知道这个工具测试过的准不准?

正则表达式中的私有 IP 地址标识符

【中文标题】正则表达式中的私有 IP 地址标识符【英文标题】:Private IP Address Identifier in Regular Expression 【发布时间】:2011-02-18 07:56:58 【问题描述】:

我想知道这是否是匹配以私有 IP 地址(Perl 风格的正则表达式)开头的字符串的最佳方式:

(^127\.0\.0\.1)|(^192\.168)|(^10\.)|(^172\.1[6-9])|(^172\.2[0-9])|(^172\.3[0-1])

非常感谢!

【问题讨论】:

首先,您应该查看 RFC1918 以获得正确的列表。其次,我建议不涉及正则表达式的解决方案更容易维护。将 IP 地址转换为数字后,很容易将其与私有 IP 范围列表进行匹配。这也可以让您轻松使用公开可用的 bogon 列表,其中包含的内容远不止 RFC1918。 @derobert true,但对于 Tomcat 远程地址过滤器等用途,您需要正则表达式。 在这种情况下认为^ 表示“不是”是一个常见的初学者错误,因此需要指出:表达式中的每个^ 只是将匹配项锚定到行首。在传统的正则表达式中,虽然 Perl 兼容 / PCRE 表达式与 (?!...) 【参考方案1】:

这是 Mark Byers 解决方案的紧凑形式:

^(172\.(1[6-9]\.|2[0-9]\.|3[0-1]\.)|192\.168\.|10\.|127\.)

【讨论】:

【参考方案2】:

晚了 10 年。感谢Mark ByersbrampEdwardblueyeduser3177026JustinkarmakazeRon Maupin

回答 TLDR

仅开始

请删除换行符 - 这只是为了便于阅读:

^(?:
127\.|
0?10\.|
172\.0?1[6-9]\.|
172\.0?2[0-9]\.|
172\.0?3[01]\.|
192\.168\.|
169\.254\.|
::1|
[fF][cCdD][0-9a-fA-F]2:|
[fF][eE][89aAbB][0-9a-fA-F]:
)

括号开头的?:表示这个括号没有被捕获,可能会让它更快一点。

请注意反斜杠。在 Postgres 例如您必须使用 E 字符串并且必须用反斜杠转义反斜杠 - 或者只使用 [.] 而不是 E'\\.'

整个 IP(十进制,前导零可选,最多三位)

请删除换行符 - 这只是为了便于阅读:

\b(
127\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|
0?10\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|
172\.0?1[6-9]\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|
172\.0?2[0-9]\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|
172\.0?3[01]\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|
192\.168\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|
169\.254\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|
::1|
[fF][cCdD][0-9a-fA-F]2(?:[:][0-9a-fA-F]0,4)0,7|
[fF][eE][89aAbB][0-9a-fA-F](?:[:][0-9a-fA-F]0,4)0,7
)
(?:\/([789]|1?[0-9]2))?
\b

https://regex101.com/r/JCLOZL/14(备份:https://etherpad.wikimedia.org/p/JCLOZL)

详情

IPv4

  127.0.0.0 to 127.255.255.255 is   127.0.0.0/8   # localhost, loopback etc.
   10.0.0.0 to  10.255.255.255 is    10.0.0.0/8   # approximately/formerly class A
 172.16.0.0 to  172.31.255.255 is  172.16.0.0/12  # approximately/formerly class B
192.168.0.0 to 192.168.255.255 is 192.168.0.0/16  # approximately/formerly class C
169.254.0.0 to 169.254.255.255 is 169.254.0.0/16  # link-local addresses since 2005

例子:

172.17.50.33 or more explicit:
172.17.50.33/32

我不确定斜线后面的部分是否可以有前导零(不太可能),但 IP 可以有前导零。

带前导零的 IPv4(十进制)

127.000.000.000 to 127.255.255.255 is 127.000.000.000/8   # localhost, loopback etc.
010.000.000.000 to 010.255.255.255 is 010.000.000.000/8   # approx/formerly class A
172.016.000.000 to 172.031.255.255 is 172.016.000.000/12  # approx/formerly class B
192.168.000.000 to 192.168.255.255 is 192.168.000.000/16  # approx/formerly class C
169.254.000.000 to 169.254.255.255 is 169.254.000.000/16  # link-local addresses

例子:

172.017.050.033 or more explicit:
172.017.050.033/32

带前导零的 IPv4(八进制)

我的正则表达式不支持。为了使您的程序完美,请检查并警告用户八进制 IP 地址和/或超过三位数!

0177.0000.0000.0000 to 0177.0377.0377.0377 is 0177.0000.0000.0000/8   # loopback
0012.0000.0000.0000 to 0012.0377.0377.0377 is 0012.0000.0000.0000/8   # A
0254.0020.0000.0000 to 0254.0037.0377.0377 is 0254.0020.0000.0000/12  # B
0300.0250.0000.0000 to 0300.0250.0377.0377 is 0300.0250.0000.0000/16  # C
0251.0376.0000.0000 to 0251.0376.0377.0377 is 0251.0376.0000.0000/16  # link-local

例子:

0254.0021.0062.0041 or more explicit:
0254.0021.0062.0041/32

是的,172.017.050.033 在不同的工具上与0254.0021.0062.0041 相同。在 macOS 上使用ping 测试。

当然,您还可以在某些工具中将十进制(无前导零)与八进制(至少一个前导零)混合使用。 :S

IPv6

fc00:0000:… to fdff:ffff:… is fc00::/7
fe80:0000:… to febf:ffff:… is fe80::/10  # link-local addresses

这可能不是您想要的,因为:

私有 IPv4 地址由 RFC 1918 定义,私有 Internet 的地址分配,并且这些地址在多个网络中使用。 IPv6 ULA 地址是唯一的(ULA 中的“U”),不能在多个地方重复使用,这就是它们需要在 Global ID 中具有 40 个随机位的原因,从而对唯一性有很高的期望。

来自公共 Internet 的所有地址都将在 2000::3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff (2000::/3) 的范围内。 您需要正确屏蔽地址以查看它是否在公共范围内,然后对公共范围内的非公共范围执行相同的操作。如果它通过了公共范围测试,则它必须在公共范围内的非公共范围内失败。如果它通过了所有这些,它就是一个公共地址。 IOT 设备还获得全球(公共)IPv6 地址。 IPv6 的重点是有足够的地址,每台设备上的每个接口都可以获得一个全局 IPv6 地址,从而恢复 IP 最初的设计方式(不再需要解决 NAT 问题)。

您的网络服务器内部的一些地址将是链接本地地址 (fe80::/10),并且可以为以下流量分配 ULA 地址(您可以从 fd00::/8 分配其中的fc00::/7,但有一定的限制)绝不允许在公共互联网上使用。

例子:

fdff:1234:abcd:5678:effe:9098:dcba:7654 or more explicit:
fdff:1234:abcd:5678:effe:9098:dcba:7654/128

不完整的链接列表

当我来到这里时,我不知道:

https://en.wikipedia.org/wiki/Private_network#Link-local_addresses https://en.wikipedia.org/wiki/Multicast_address (224.0.0.0/24) https://***.com/a/46399203/1707015

【讨论】:

【参考方案3】:

如果超过一位,您需要一个结束分隔符来获取整个第 4 个八位字节。

^(10.([0-9][0-9]?|[0-1][0-9]?[0-9]?|2[0-4]?[0-9] ?|25[0-5])|172.(1[6-9]|2[0-9]|3[0-1])|192.168).([0-9][0-9]? |[0-1][0-9]?[0-9]?|2[0-4]?[0-9]?|25[0-5]).([0-9][0- 9]?|[0-1][0-9]?[0-9]?|2[0-4]?[0-9]?|25[0-5])$

【讨论】:

【参考方案4】:

我已经生成了这个

A 类网络的正则表达式:

(10)(\.([2]([0-5][0-5]|[01234][6-9])|[1][0-9][0-9]|[1-9][0-9]|[0-9]))3

B 类网络的正则表达式:

(172)\.(1[6-9]|2[0-9]|3[0-1])(\.(2[0-4][0-9]|25[0-5]|[1][0-9][0-9]|[1-9][0-9]|[0-9]))2

C 类网络的正则表达式:

(192)\.(168)(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9]))2

如果您遇到任何错误,请告诉我

如果您确定您的输出(例如 netstat)并且您不需要检查 IP 地址的有效性,因为它已经完成,那么您可以使用此公式捕获私有 IP 地址

grep -P "(10.|192.168|172.1[6-9].|172.2[0-9].|172.3[01].).* "

【讨论】:

仅将[2][0-5][0-5] 用于 200 到 255 的范围,206 到 209 和 216 到 219 等数字将不匹配。您必须将其替换为 ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) 这是用于什么语言的?我无法让它工作,regex101.com/r/jdVmny/1【参考方案5】:

这是我在 python 中使用的:

rfc1918 = re.compile('^(10(\.(25[0-5]|2[0-4][0-9]|1[0-9]1,2|[0-9]1,2))3|((172\.(1[6-9]|2[0-9]|3[01]))|192\.168)(\.(25[0-5]|2[0-4][0-9]|1[0-9]1,2|[0-9]1,2))2)$')

如果您愿意,可以删除 ^ 和/或 $ 锚。

我更喜欢上面的正则表达式,因为它会清除无效的八位字节(任何高于 255 的字节)。

示例用法:

if rfc1918.match(ip):
    print "ip is private"

【讨论】:

【参考方案6】:
     //RegEx to check for the following ranges. IPv4 only
         //172.16-31.xxx.xxx
         //10.xxx.xxx.xxx
         //169.254.xxx.xxx
         //192.168.xxx.xxx

     var regex = /(^127\.)|(^(0)?10\.)|(^172\.(0)?1[6-9]\.)|(^172\.(0)?2[0-9]\.)|(^172\.(0)?3[0-1]\.)|(^169\.254\.)|(^192\.168\.)/;

【讨论】:

【参考方案7】:

使用pattern.matcher,这种模式的速度提高了 10% 以上:

^1((0)|(92\\.168)|(72\\.((1[6-9])|(2[0-9])|(3[0-1])))|(27))\\.

【讨论】:

我做了一些测试,但它似乎慢了 100%。您能否提供一些测试来支持这一点?【参考方案8】:

我假设你想匹配这些范围:

127. 0.0.0 – 127.255.255.255 127.0.0.0 /8 10. 0.0.0 – 10.255.255.255 10.0.0.0 /8 172. 16.0.0 – 172. 31.255.255 172.16.0.0 /12 192.168.0.0 - 192.168.255.255 192.168.0.0 /16

您缺少一些会导致它接受的点,例如172.169.0.0,即使这不应该被接受。我已经在下面修复了它。删除新行,只是为了便于阅读。

(^127\.)|
(^10\.)|
(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|
(^192\.168\.)

另请注意,这假定 IP 地址已经过验证 - 它接受 10.foobar 之类的内容。

【讨论】:

如果你想从谷歌分析跟踪中排除私人 IP 地址,使用这个:gist.github.com/1000402 第一行应该是 (^127\.)| Java 版本:'(^127\\.0\\.0\\.1)|(^10\\.)|(^172\\.1[6-9]\\.)|(^172\\.2[0-9]\\.)|(^172\\.3[0-1]\\.)|(^192\\.168\\.)' 更复杂但更准确:(^127\.[0-9]1,3\.[0-9]1,3\.[0-9]1,3$)|(^10\.[0-9]1,3\.[0-9]1,3\.[0-9]1,3$)|(^172\.1[6-9]1[0-9]0,1\.[0-9]1,3\.[0-9]1,3$)|(^172\.2[0-9]1[0-9]0,1\.[0-9]1,3\.[0-9]1,3$)|(^172\.3[0-1]1[0-9]0,1\.[0-9]1,3\.[0-9]1,3$)|(^192\.168\.[0-9]1,3\.[0-9]1,3$) 自动链接本地私有地址 169.254.*.* 也应该在这个集合中。写得很紧凑:^(10|127|169\.254|172\.1[6-9]|172\.2[0-9]|172\.3[0-1]|192\.168)\.【参考方案9】:

这与 Mark 的正确答案相同,但现在包括 IPv6 私有地址。

/(^127\.)|(^192\.168\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^::1$)|(^[fF][cCdD])/

【讨论】:

不好 - 根据*** (en.wikipedia.org/wiki/Unique_local_address),块 (fc00::/7) 是为唯一本地地址保留的。此 Regex 仅将 localhost 地址 (::1) 添加到已接受的解决方案中。 根据github.com/rails/rails/pull/12651/files 的正则表达式将是^[fF][cCdD] - 我正在相应地编辑答案。 脚本开头和结尾处的/ 字符表明您正在使用某种语言(如Javascript)中的表达式,但这在其他语言中无效。尽管如此,一个较短的版本(没有斜线)是^(127\.)|(192\.168\.)|(10\.)|(172\.1[6-9]\.)|(172\.2[0-9]\.)|(172\.3[0-1]\.)|(::1$)|([fF][cCdD]) @MarianoRuiz 我相信如果你在开头有插入符号,你需要一个捕获组,否则你最终匹配 127. 在开头,其余组在字符串。【参考方案10】:

如果您正在寻找 system.net defaultProxy 和 proxy bypasslist 配置,该配置使用外部代理但内部主机使用直接连接(可以使用一些 ipv6 支持)...

<system.net>
  <defaultProxy enabled="true">
    <proxy proxyaddress="http://proxycluster.privatedomain.net:8080" bypassonlocal="True"  />
    <bypasslist>
      <!-- exclude local host -->
      <add address="^(http|https)://localhost$" />
      <!-- excludes *.privatedomain.net -->
      <add address="^(http|https)://.*\.privatedomain\.net$" />
      <!-- excludes simple host names -->
      <add address="^(http|https)://[a-z][a-z0-9\-_]*$" />
      <!-- exclude private network addresses 192.168, 172.16..31 through 31, 127.* etc. -->
      <add address="^(http|https)://((((127)|(10))\.[0-9]+\.[0-9]+\.[0-9]+)|(((172\.(1[6-9]|2[0-9]|3[0-1]))|(192\.168))\.[0-9]+\.[0-9]+))$"/>
    </bypasslist>
  </defaultProxy>
  <connectionManagement>
    <add address="*" maxconnection="10" />
  </connectionManagement>
</system.net>

【讨论】:

【参考方案11】:

看起来不错。就个人而言,我会将第一个更改为:

^127\.0 

有了这个:(^127\.0\.0\.1) 你正在寻找以127.0.0.1 开头的任何东西,并且会错过127.0.0.2*127.0.2.*127.0.* 等。

【讨论】:

我知道这很旧,但这个问题在我的谷歌搜索中是第一或第二。我相信整个 127.0.0.0/8 块是为环回保留的,所以 0 甚至不应该在那里。【参考方案12】:

如果您决定接受我的评论,建议您不要使用正则表达式。在 Perl 中未经测试(但可能有效,或至少接近):

@private = (
    network => inet_aton('127.0.0.0'),   mask => inet_aton('255.0.0.0')   ,
    network => inet_aton('192.168.0.0'), mask => inet_aton('255.255.0.0') ,
    # ...
);

$ip = inet_aton($ip_text);
if (grep $ip & $_->mask == $_->network, @private) 
    # ip address is private
 else 
    # ip address is not private

现在请注意@private 只是数据,您可以轻松更改它。或从Cymru Bogon Reference 即时下载。

edit:在我看来,请求 Perl 正则表达式并不意味着您知道 Perl,所以关键行是“grep”,它只是在每个私有地址范围内循环。你把你的IP,按位和它与网络掩码,并与网络地址进行比较。如果相等,则为该专用网络的一部分。

【讨论】:

以上是关于如何用正则表达式匹配出如下代码中的IP地址跟IP地址归属地?的主要内容,如果未能解决你的问题,请参考以下文章

如何用正则表达式检测ip是不是正确,求详解

在linux下如何用正则表达式执行ifconfig命令,只提取IP地址!

如何用正则表达式在JS中匹配出相应的拓展名?

正则表达式,匹配IP地址的,求大神帮我解释这行代码。^([1-9][1-9][0-9]1[0-

python实战系列之正则获取IP地址

如何用excel中的VBA的正则表达式提取出字符串?