2016-12-21 4 views
1

Интересно, возможно ли это. У меня есть картина:PCRE накапливает несколько встречных совпадений группы

foo:(?<id>\d+)(?::(?<srcid>\d+))*

Теперь матч на этом образце:

asdasdasd {{foo:1381:2:4:7}}

я получаю матч:

Full match  `foo:1381:2:4:7` 
Group `id`  `1381` 
Group `srcid` `7` 

Однако, это возможно, чтобы получить таких как:

Full match  `foo:1381:2:4:7` 
Group `id`  `1381` 
Group `srcid` [`2`, `4`, `7`] 

Мне нужно это для работы с несколькими совпадениями, например. asdasdasd {{foo:1381:2:4:7}} {{foo:1111}}.

+0

Не в одном шаге. Вы можете либо сопоставить все числа 'srcid', либо разделить потом, либо использовать' \ G' и сопоставлять несколько раз, где 'id' содержится только в первом совпадении. –

ответ

1

Вы можете использовать \G в вашем PCRE регулярное выражение, чтобы получить несколько матчей после окончания предыдущего матча:

(?:{{foo:(?<id>\d+)|(?<!^)\G)(?::(?<srcid>\d+)|}}) 

RegEx Demo

\G утверждает положение в конце предыдущего матча или в начале строки для первого матча.

Пример кода:

$str = 'asdasdasd {{foo:1381:2:4:7}}'; 
preg_match_all('/(?:foo:(?<id>\d+)|(?<!^)\G):(?<srcid>\d+)/', $str, $m); 

print_r($m['srcid']); 
echo $m['id'][0]; // 1381 

Выход:

Array 
(
    [0] => 2 
    [1] => 4 
    [2] => 7 
) 
1381 
+0

Спасибо за ваш ответ! Я должен был указать, что мне нужно это, чтобы работать с несколькими совпадениями всей группы. Кажется, что не работает правильно, когда я пытаюсь, например. '{{foo: 1381: 2: 4: 7}} {{foo: 1111}}'. Тогда второй id пуст. Это также возможно? – ypnos

+0

ok проверить мое обновленное регулярное выражение и новую демонстрационную ссылку – anubhava

+1

Удивительно, работает как шарм! – ypnos