Логический способ обратной трассировки соответствующего регулярного выражения из операции ИЛИ (|) - PullRequest
1 голос
/ 09 мая 2019

При выполнении preg_match с 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)|...

массив результатов будет содержать ключ MARK, содержащий 'some-name'. Идея здесь состоит в том, чтобы иметь отдельную структуру данных, которая отображает 'some-name' в соответствующее регулярное выражение. Это позволяет легко использовать сброс ветви "? |"

1 Ответ

0 голосов
/ 09 мая 2019

Вы можете сначала определить массив группового шаблона, использовать не перехватывающую группу вместо сброса ветви, обернуть каждую альтернативу именованной группой после массива группового шаблона и назвать каждую подгруппу именем группы в качестве суффикса. .

Тогда вы можете использовать

$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 демо

Выход:

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