2016-02-28 68 views
2

试图搜索已经回答的问题,但...找不到任何东西。 我试图做一个正则表达式将匹配IPv4或IPv4的:端口REGEX:无条件匹配

$regex_ipv4 = '((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))(?![\\d])'; 
$regex_integer = '(\\d+)'; 

$x = "123.123.123.123"; 
$x2 = $x . ":12345"; 

preg_match("/^(?<ipv4>".$regex_ipv4.")(:)(?<port>".$regex_integer.")$/is", $x, $matches1); 
preg_match("/^(?<ipv4>".$regex_ipv4.")(:)(?<port>".$regex_integer.")$/is", $x2, $matches2); 

print_r($matches1); 
print_r($matches2); 

回报:

Array 
(
) 
Array 
(
    [0] => 123.123.123.123:12345 
    [ipv4] => 123.123.123.123 
    [1] => 123.123.123.123 
    [2] => 123.123.123.123 
    [3] => : 
    [port] => 12345 
    [4] => 12345 
    [5] => 12345 
) 

我怎样才能使(:)(?<port>".$regex_integer.")无条件的比赛?

谢谢!

+1

什么你的意思是“无条件地匹配......”吗? –

+0

'((:)(?“。$ regex_integer。”))?'? –

+0

看起来代码正在工作,命名组捕获你所需要的。 –

回答

1

您必须在模式结尾处搜索可选组。它可以是这样的:

^(?<ipv4>((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))(?!\d))(?::(?<port>\d+))?$ 

regex demo

在你的代码,使用

preg_match("/^(?<ipv4>".$regex_ipv4.")(?::(?<port>".$regex_integer."))?$/", $x, $matches); 

注意,一个:周围捕获组是多余的。 (?:开始非捕获组,)?在正则表达式关闭组和?量词使正则表达式引擎匹配该组1或0次。

而且清理正则表达式模式,我建议删除多余的字符类只是一个符号和多余的捕捉组:

$regex_ipv4 = "((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))(?!\\d)"; 
$regex_integer = "\\d+"; 

这里是一个complete PHP demo

$regex_ipv4 = "((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))(?!\\d)"; 
$regex_integer = "\\d+"; 

$x = "123.123.123.123"; 
$x2 = $x . ":12345"; 

preg_match("/^(?<ipv4>".$regex_ipv4.")(?::(?<port>".$regex_integer."))?$/", $x, $matches); 
preg_match("/^(?<ipv4>".$regex_ipv4.")(?::(?<port>".$regex_integer."))?$/", $x2, $matches2); 

print_r($matches); 
print_r($matches2); 
+0

谢谢!成功了! – user3405598