检查字符串是否包含 PHP 中的 IPV6 地址
Check if a string contains an IPV6 address in PHP
使用 PHP,我需要检查字符串是否包含 IPv6 地址 - 如果包含,然后提取该 IPv6 地址。
我有一个匹配字符串的正则表达式,如果它恰好是 IPv6:
$matches = [];
$regex = '/^(((?=.*(::))(?!.*.+))?|([\dA-F]{1,4}(|:\b|$)|))(?4){5}((?4){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4})\z/i';
preg_match($regex, $ipv6, $matches);
我坚持的是能够在任一侧添加通配符,因此我可以匹配如下内容:
- http://2001:0db8:85a3:0000:0000:8a2e:0370:7334/something/page.html
- http://2001:0db8:85a3:0000:0000:8a2e:0370:7334
- 2001:0db8:85a3:0000:0000:8a2e:0370:7334/something/page.html
最终我需要这样做,这样我就可以用方括号括起 IPv6 地址,使其符合 RFC 3986(例如 http://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]/something/page.html
)。
您需要使用另一个正则表达式,例如 this:
(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))
之后,您可以将 ipv6 包装在 link:
<?php
$ipv6 = 'http://2001:0db8:85a3:0000:0000:8a2e:0370:7334/something/page.html';
$matches = [];
$regex = '(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))';
if (preg_match($regex, $ipv6, $matches)) {
$result = str_replace($matches[0], '[' . $matches[0] . ']', $ipv6);
}
简介
我还没有完全测试代码,所以我不能 100% 确定它能正常工作,但是,我 运行 它针对几个不同的 URL,它似乎工作正常。
我已经采纳了部分答案:
- Looking to build some regex to validate domain names (RFC 952/ RFC 1123)
- What is the RFC complicant and working regular expression to check if a string is a valid URL
- Regular expression that matches valid IPv6 addresses
回答
用域名回答
这是我想出的:
(?(DEFINE)
(?<scheme>[a-z][a-z0-9+.-]*)
(?<userpass>([^:@\/](:[^:@\/])?@))
(?<domain>[a-z0-9]+(-[a-z0-9]+)*(\.[a-z0-9]+(-[a-z0-9]+)*)+)
(?<ip>(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])))
(?<host>((?&domain)|(?&ip)))
(?<port>(:[\d]{1,5}))
(?<path>([^?;\#]*))
(?<query>(\?[^\#;]*))
(?<anchor>(\#.*))
)
^(?:(?&scheme):\/\/)?(?&userpass)?(?<address>(?&host))(?&port)?\/?(?&path)?(?&query)?(?&anchor)?$
关注 this link 查看它的使用情况
没有域名的回答
以上正则表达式将匹配包含有效域(无论是域名还是地址)的 URL。如果您只想匹配 IP 地址,请使用以下正则表达式(其中包括对名为 host
的定义组的简单更改 - 我删除了对名为 domain
)
(?(DEFINE)
(?<scheme>[a-z][a-z0-9+.-]*)
(?<userpass>([^:@\/](:[^:@\/])?@))
(?<domain>[a-z0-9]+(-[a-z0-9]+)*(\.[a-z0-9]+(-[a-z0-9]+)*)+)
(?<ip>(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])))
(?<host>(?&ip))
(?<port>(:[\d]{1,5}))
(?<path>([^?;\#]*))
(?<query>(\?[^\#;]*))
(?<anchor>(\#.*))
)
^(?:(?&scheme):\/\/)?(?&userpass)?(?<address>(?&host))(?&port)?\/?(?&path)?(?&query)?(?&anchor)?$
关注 this link 查看它的使用情况
对于那些喜欢冗长的难以辨认的查询的人,您可以使用以下与上面的正则表达式等效的正则表达式。
^(?:[a-z][a-z0-9+.-]*:\/\/)?(?:[^:@\/](?::[^:@\/])?@)?(?<address>(?:[0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:(?:(?::[0-9a-fA-F]{1,4}){1,6})|:(?:(?::[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(?::[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(?:ffff(?::0{1,4}){0,1}:){0,1}(?:(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])|(?:[0-9a-fA-F]{1,4}:){1,4}:(?:(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9]))(?::[\d]{1,5})?\/?(?:[^?;\#]*)?(?:\?[^\#;]*)?(?:\#.*)?$
注意:两个答案都使用 i
(不区分大小写)和 x
(忽略空格)修饰符
也许 2 个正则表达式匹配会更好。因为你的正则表达式看起来很复杂
$regex1 = '/^https?:\/\/([a-z0-9:]{39})/';
if( preg_match( $regex1, $your_text, $matches1) ) {
$regex2 = '/[a-z0-9]{4}:?/';
if( preg_match_all( $regex2, $matches1[1], $matches2 ) === 8 )
echo $your_text.' qualifies!!';
}
您不需要难以阅读和理解 regex
即可验证字符串是否为有效的 IPv6 地址。 PHP 函数 filter_var()
可以为您完成繁重的工作:
echo(filter_var('2001:0db8:85a3:0000:0000:8a2e:0370:7334', FILTER_VALIDATE_IP));
# 2001:0db8:85a3:0000:0000:8a2e:0370:7334
echo(filter_var('2001:0db8:85a3::8a2e:0370:7334', FILTER_VALIDATE_IP));
# 2001:0db8:85a3::8a2e:0370:7334
echo(filter_var('192.168.0.1', FILTER_VALIDATE_IP));
# 192.168.0.1
var_dump(filter_var('192.168.0.1', FILTER_VALIDATE_IP, FILTER_FLAG_IPV6));
# bool(false)
它 returns 如果输入值有效(根据作为第二个参数传递的过滤器和作为第三个参数传递的选项),否则为 FALSE。
如果 IP 地址是 URL 的域,则可以使用 PHP 函数 parse_url()
提取它:
print_r(parse_url('http://2001:0db8:85a3:0000:0000:8a2e:0370:7334/something/page.html'));
# Array
# (
# [scheme] => http
# [host] => 2001:0db8:85a3:0000:0000:8a2e:0370:7334
# [path] => /something/page.html
# )
示例中的最后一个字符串 (2001:0db8:85a3:0000:0000:8a2e:0370:7334/something/page.html
) 不是 URL。它只是一些随机文本,恰好看起来像不完整(且无效)URL。我没有简单的解决方案:-(
使用 PHP,我需要检查字符串是否包含 IPv6 地址 - 如果包含,然后提取该 IPv6 地址。
我有一个匹配字符串的正则表达式,如果它恰好是 IPv6:
$matches = [];
$regex = '/^(((?=.*(::))(?!.*.+))?|([\dA-F]{1,4}(|:\b|$)|))(?4){5}((?4){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4})\z/i';
preg_match($regex, $ipv6, $matches);
我坚持的是能够在任一侧添加通配符,因此我可以匹配如下内容:
- http://2001:0db8:85a3:0000:0000:8a2e:0370:7334/something/page.html
- http://2001:0db8:85a3:0000:0000:8a2e:0370:7334
- 2001:0db8:85a3:0000:0000:8a2e:0370:7334/something/page.html
最终我需要这样做,这样我就可以用方括号括起 IPv6 地址,使其符合 RFC 3986(例如 http://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]/something/page.html
)。
您需要使用另一个正则表达式,例如 this:
(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))
之后,您可以将 ipv6 包装在 link:
<?php
$ipv6 = 'http://2001:0db8:85a3:0000:0000:8a2e:0370:7334/something/page.html';
$matches = [];
$regex = '(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))';
if (preg_match($regex, $ipv6, $matches)) {
$result = str_replace($matches[0], '[' . $matches[0] . ']', $ipv6);
}
简介
我还没有完全测试代码,所以我不能 100% 确定它能正常工作,但是,我 运行 它针对几个不同的 URL,它似乎工作正常。
我已经采纳了部分答案:
- Looking to build some regex to validate domain names (RFC 952/ RFC 1123)
- What is the RFC complicant and working regular expression to check if a string is a valid URL
- Regular expression that matches valid IPv6 addresses
回答
用域名回答
这是我想出的:
(?(DEFINE)
(?<scheme>[a-z][a-z0-9+.-]*)
(?<userpass>([^:@\/](:[^:@\/])?@))
(?<domain>[a-z0-9]+(-[a-z0-9]+)*(\.[a-z0-9]+(-[a-z0-9]+)*)+)
(?<ip>(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])))
(?<host>((?&domain)|(?&ip)))
(?<port>(:[\d]{1,5}))
(?<path>([^?;\#]*))
(?<query>(\?[^\#;]*))
(?<anchor>(\#.*))
)
^(?:(?&scheme):\/\/)?(?&userpass)?(?<address>(?&host))(?&port)?\/?(?&path)?(?&query)?(?&anchor)?$
关注 this link 查看它的使用情况
没有域名的回答
以上正则表达式将匹配包含有效域(无论是域名还是地址)的 URL。如果您只想匹配 IP 地址,请使用以下正则表达式(其中包括对名为 host
的定义组的简单更改 - 我删除了对名为 domain
)
(?(DEFINE)
(?<scheme>[a-z][a-z0-9+.-]*)
(?<userpass>([^:@\/](:[^:@\/])?@))
(?<domain>[a-z0-9]+(-[a-z0-9]+)*(\.[a-z0-9]+(-[a-z0-9]+)*)+)
(?<ip>(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])))
(?<host>(?&ip))
(?<port>(:[\d]{1,5}))
(?<path>([^?;\#]*))
(?<query>(\?[^\#;]*))
(?<anchor>(\#.*))
)
^(?:(?&scheme):\/\/)?(?&userpass)?(?<address>(?&host))(?&port)?\/?(?&path)?(?&query)?(?&anchor)?$
关注 this link 查看它的使用情况
对于那些喜欢冗长的难以辨认的查询的人,您可以使用以下与上面的正则表达式等效的正则表达式。
^(?:[a-z][a-z0-9+.-]*:\/\/)?(?:[^:@\/](?::[^:@\/])?@)?(?<address>(?:[0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:(?:(?::[0-9a-fA-F]{1,4}){1,6})|:(?:(?::[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(?::[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(?:ffff(?::0{1,4}){0,1}:){0,1}(?:(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])|(?:[0-9a-fA-F]{1,4}:){1,4}:(?:(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9]))(?::[\d]{1,5})?\/?(?:[^?;\#]*)?(?:\?[^\#;]*)?(?:\#.*)?$
注意:两个答案都使用 i
(不区分大小写)和 x
(忽略空格)修饰符
也许 2 个正则表达式匹配会更好。因为你的正则表达式看起来很复杂
$regex1 = '/^https?:\/\/([a-z0-9:]{39})/';
if( preg_match( $regex1, $your_text, $matches1) ) {
$regex2 = '/[a-z0-9]{4}:?/';
if( preg_match_all( $regex2, $matches1[1], $matches2 ) === 8 )
echo $your_text.' qualifies!!';
}
您不需要难以阅读和理解 regex
即可验证字符串是否为有效的 IPv6 地址。 PHP 函数 filter_var()
可以为您完成繁重的工作:
echo(filter_var('2001:0db8:85a3:0000:0000:8a2e:0370:7334', FILTER_VALIDATE_IP));
# 2001:0db8:85a3:0000:0000:8a2e:0370:7334
echo(filter_var('2001:0db8:85a3::8a2e:0370:7334', FILTER_VALIDATE_IP));
# 2001:0db8:85a3::8a2e:0370:7334
echo(filter_var('192.168.0.1', FILTER_VALIDATE_IP));
# 192.168.0.1
var_dump(filter_var('192.168.0.1', FILTER_VALIDATE_IP, FILTER_FLAG_IPV6));
# bool(false)
它 returns 如果输入值有效(根据作为第二个参数传递的过滤器和作为第三个参数传递的选项),否则为 FALSE。
如果 IP 地址是 URL 的域,则可以使用 PHP 函数 parse_url()
提取它:
print_r(parse_url('http://2001:0db8:85a3:0000:0000:8a2e:0370:7334/something/page.html'));
# Array
# (
# [scheme] => http
# [host] => 2001:0db8:85a3:0000:0000:8a2e:0370:7334
# [path] => /something/page.html
# )
示例中的最后一个字符串 (2001:0db8:85a3:0000:0000:8a2e:0370:7334/something/page.html
) 不是 URL。它只是一些随机文本,恰好看起来像不完整(且无效)URL。我没有简单的解决方案:-(