REGEX:非条件匹配

时间:2016-02-28 14:38:07

标签: php regex

试图搜索已经回答的问题,但是......找不到任何东西。 我试图创建一个匹配ipv4或ipv4:port

的正则表达式
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.")

如何对#include <memory> #include <iostream> #include <stdexcept> using widget = std::unique_ptr<int>; struct sink_1 { sink_1(widget&& w) { throw std::runtime_error("error"); w_ = std::move(w); } widget w_; }; struct sink_2 { sink_2(widget w) { throw std::runtime_error("error"); w_ = std::move(w); } widget w_; }; int main(int argc, char *argv[]) { auto w1 = std::make_unique<int>(10); auto w2 = std::make_unique<int>(20); try { sink_1 s1(std::move(w1)); } catch (std::runtime_error &e) { std::cout << *w1 << std::endl; } try { sink_2 s2(std::move(w2)); } catch (std::runtime_error &e) { std::cout << *w2 << std::endl; // crashes } return 0; } 进行无条件匹配?

谢谢!

1 个答案:

答案 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);