正则表达式:非条件匹配


REGEX: Non-conditional match

试图搜索已经回答的问题,但是...什么都找不到。我正在尝试制作一个与 ipv4 或 ipv4:port 匹配的正则表达式

$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.")

谢谢!

您必须在

模式末尾搜索可选组。它可能看起来像:

^(?<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+))?$

查看正则表达式演示

在代码中,使用

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+";

这是一个完整的PHP演示:

$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);