Получить повторные матчи с preg match all()
Я пытаюсь получить все подстроки, соответствующие множителю:
$list = '1,2,3,4';
preg_match_all('|d+(,d+)*|', $list, $matches);
print_r($matches);
Этот пример возвращает, как и ожидалось, последнее совпадение в [1]
:
Array
(
[0] => Array
(
[0] => 1,2,3,4
)
[1] => Array
(
[0] => ,4
)
)
Однако, я хотел бы получить все строки, соответствующие (,d+)
, чтобы получить что-то вроде:
Array
(
[0] => ,2
[1] => ,3
[2] => ,4
)
Есть ли способ сделать это с помощью одной функции, такой как preg_match_all()
?6 ответов:
Согласно Коби (см. комментарии выше):
PHP не поддерживает захваты одной и той же группы
Поэтому этот вопрос не имеет решения.
Использование lookbehind - это способ выполнить работу:
$list = '1,2,3,4'; preg_match_all('|(?<=\d),\d+|', $list, $matches); print_r($matches);
Все
,\d+
находятся в группе 0.Вывод:
Array ( [0] => Array ( [0] => ,2 [1] => ,3 [2] => ,4 ) )
Разбиение-это только вариант, когда символ для разбиения не используется в шаблонах, чтобы соответствовать самому себе. У меня была ситуация, когда плохо отформатированная строка, разделенная запятыми, должна быть разбита на любой из известных вариантов.
То есть варианты '1,2', '2', '2,3' тема '1,2,3'.
Разбиение на ', ' приведет к '1', '2' и '3'; только один ('2') из которых является допустимым соответствием, это происходит потому, что разделитель также является частью опций.
Наивное регулярное выражение было бы чем-то как будто '~^(1,2|2|2,3)(?:,(1,2|2|2,3))*$~i', но это упирается в проблему одногруппных захватов.
Мое "решение" состояло в том, чтобы просто расширить регулярное выражение, чтобы соответствовать максимальному количеству возможных совпадений: '~^(1,2|2|2,3)(?:,(1,2|2|2,3))?(?:,(1,2|2|2,3))?$~i' (если были доступны другие варианты, просто повторите' (?:,(1,2|2|2,3))?' немного. Это приводит к пустой строке результатов для "неиспользуемых" матчей.
Это не самое чистое решение, но работает, когда вам приходится иметь дело с плохо отформатированным входом данные.
Из http://www.php.net/manual/en/regexp.reference.repetition.php :
Когда подшаблон захвата повторяется, захваченное значение является подстрокой, которая соответствовала последней итерации.
Также аналогичная нить:
Как получить все записи матчей подгрупп с помощью preg_match_all()?