如何用正则表达式匹配出如下代码中的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>
地址 (?<=您所在的地址是:<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 Byers
、bramp
、Edward
、blueyed
、user3177026
、Justin
、karmakaze
、Ron 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地址归属地?的主要内容,如果未能解决你的问题,请参考以下文章
在linux下如何用正则表达式执行ifconfig命令,只提取IP地址!