从 OR (|) 操作回溯相应正则表达式的逻辑方法

A logical way to back trace the corresponding regex from an OR (|) operation

While 运行 a preg_match with OR (|), 是否有一种合乎逻辑的方法来确定匹配的正则表达式。

@regex = ~^(?|/|/about|/about/class/(?<id>[^/]+)/fox|/about/class/(?<id>[^/]+)/(?<type>[^/]+)/fox|/about/class/(?<id>[^/]+)/(?<type>[^/]+)/fox/(?<boat>[^/]+))$~x

preg_match(@regex, '/about/class/test1/test2/fox', $results); 

该示例将匹配并根据需要为我提供命名组

matches /about/class/(?<id>[^/]+)/(?<type>[^/]+)/fox in @regex
id = test1
type = test2

是否有合理的方法来查找匹配@regex 的部分?

找到解决方案:

|/about/class/([^/]+)/fox(*MARK:some-name)|...

结果数组将包含一个包含 'some-name' 的 MARK 键。这里的想法是有一个单独的数据结构,将 'some-name' 映射到相应的正则表达式。这允许轻松使用分支重置“?|”

您可以先定义一个 group-pattern 数组,使用 non-capturing 组而不是分支重置,在 group-pattern 数组后用一个命名组包装每个备选方案并命名每个 sub-group以组名作为后缀。

那么你可以使用

$groupmap = ['one' => '/', 'two' => '/about', 'three' => '/about/class/(?<id>[^/]+)/fox',
             'five' => '/about/class/(?<id>[^/]+)/(?<type>[^/]+)/fox/(?<boat>[^/]+)'];
$regex = '~^(?:(?<one>/)|(?<two>/about)|(?<three>/about/class/(?<idthree>[^/]+)/fox)|(?<four>/about/class/(?<idfour>[^/]+)/(?<typefour>[^/]+)/fox)|(?<five>/about/class/(?<idfive>[^/]+)/(?<typefive>[^/]+)/fox/(?<boatfive>[^/]+)))$~x';
if (preg_match($regex, '/about/class/test1/test2/fox/someboat', $m)) {
    foreach ($groupmap as $name => $pattern ) {
       if (isset($m[$name]) && !empty($m[$name])) {
           echo "Group '" . $name . "' matched: " . $pattern . "\n";
           echo "ID: " . (!empty($m["id".$name]) ? $m["id".$name] : "None") . "\n";
           echo "TYPE: " . (!empty($m["type".$name]) ? $m["type".$name] : "None") . "\n";
           echo "BOAT: " . (!empty($m["boat".$name]) ? $m["boat".$name] : "None");
       }
    }
}

PHP demo

输出:

Group 'five' matched: /about/class/(?<id>[^/]+)/(?<type>[^/]+)/fox/(?<boat>[^/]+)
ID: test1
TYPE: test2
BOAT: someboat