Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PHP中检查字符串是否包含IPV6地址_Php_Regex_Ipv6 - Fatal编程技术网

在PHP中检查字符串是否包含IPV6地址

在PHP中检查字符串是否包含IPV6地址,php,regex,ipv6,Php,Regex,Ipv6,使用PHP,我需要检查字符串是否包含IPv6地址,如果包含,则提取该IPv6地址 我有一个正则表达式,它与一个字符串匹配,如果它确实是一个IPv6: $matches = []; $regex = '/^(((?=.*(::))(?!.*\3.+\3))\3?|([\dA-F]{1,4}(\3|:\b|$)|\2))(?4){5}((?4){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4})\z/i'; preg_match($regex, $ipv6,

使用PHP,我需要检查字符串是否包含IPv6地址,如果包含,则提取该IPv6地址

我有一个正则表达式,它与一个字符串匹配,如果它确实是一个IPv6:

$matches = [];
$regex = '/^(((?=.*(::))(?!.*\3.+\3))\3?|([\dA-F]{1,4}(\3|:\b|$)|\2))(?4){5}((?4){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4})\z/i';
preg_match($regex, $ipv6, $matches);
我一直坚持的是能够在任意一侧添加通配符,这样我就可以匹配以下内容:

  • 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

您需要使用另一个regexp,如:

之后,您可以在链接中包装ipv6:

<?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上运行了它,它似乎工作正常

我已经回答了部分问题:

答复 用域名回答 这就是我想到的:

(?(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)?$
按照链接查看它的使用情况

对于那些喜欢长而不清晰的查询的人,可以使用下面的正则表达式,它与上面的正则表达式相同

^(?:[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})?\/?(?:[^?;\#]*)?(?:\?[^\#;]*)?(?:\#.*)?$
以下几名::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::[0-9a-9a-a-a-a-a-a-fA-fA-fA-F[[[[1-a-a-a-a-a-fA-fA-F][[1,1,1,4[1,4}[1,4}:[1,4}::[1,4}:[1,4}:::[1,4}:::::[1.5[1,4[1,4}:[1,4}:[1,4[1,4}:[1.5[1,4}:[1,4}:[1,4}:[1,4}::::[0-9a-9a-FaA-FaA-FaA-FaA-fA-Fa0-9a-FaA-FaA-F[1,1,4}{1,1,2}[[1,2}}(:::[0-9a-9a-9a-fA-fA-F[0-9a-a-a-fA-FaA-fA-F[0-0-9a-a-a-a-a-a-fA-fA-fA-fA-fA-fA-F[0 0-0-a-a-a-a-fA-Fa0-Fa0-fA-F[[[0 0-0-0-0-0-0-0-0-0-0-0-a-a-a-a-a-fA-a-a-fA-a-fA-fA-fA-fA-fA-fA-fA-F[0[0[[0[0[0[0[0 0[0 0 0[fA-F]{1,1,4}}::{{1,1,4}{{1,1,4 5 5}::{{1,1,4}::{{1,1,4}:::{{1,4}::{1,1,4}::{{1,1,1,4}::::{{1,1,1,4}}}::::::::{{{{1,1,1,1,4}::::::::::::::::[0-0-0-0-9a-9a-9a-9a-9a-A-A-A-A-A-A-A-A-A-fA-fA-fA-fA-fA-fA-F-fA-F-F[0-F[0-F[1,1,1,1,1,1,4}{{1,4}1,4}}{以下:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::)0 0 0 0 0.0.0.0 ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::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!!'; 
}

要验证字符串是否是有效的IPv6地址,您不需要阅读和理解
regex
。PHP函数可以为您执行重磅提升:

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)
如果输入值有效(根据作为第二个参数传递的过滤器和作为第三个参数传递的选项),则返回输入值,否则返回FALSE

如果IP地址是URL的域,则可以使用PHP函数提取该地址:

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。它只是一些看起来不完整(无效)的随机文本。我没有简单的解决方案:-(

在模式中不完全描述IPv6语法的情况下,您可以使用
解析url
(当方案是一个数字时,然后添加一个假方案以获得正确的主机)和
过滤器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)
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
# )