2016-02-19 2 views
6

У меня есть строка, как это:Как создать динамическую группу захвата в регулярном выражении?

$str =" 
- group1 
- group2 
- group3 
"; 

Также у меня есть этот regex:

/(\-\s\w+)\n(\-\s\w+)\n(\-\s\w+)/ 

Как вы знаете, есть три группы захвата: $1, $2 и $3. Я сделал эту группу вручную. Я имею в виду, если я добавлю это в строку выше:

- group4 
- group5 

Тогда это регулярное выражение не соответствует им.


Ну, у меня есть постоянная закономерность: (\-\s\w+), И я хочу, чтобы создать отделенную группу захвата по количеству матчей элементов в строке. Заяц несколько примеров:

example1:

$str=" 
- group 1 
"; 

мне нужно регулярное выражение, чтобы дать мне всю строку, $1.


Example2:

$str=" 
- group 1 
- group 2 
"; 

мне нужно регулярное выражение, чтобы дать мне первую линию строки (- group 1) по $1 и второй линии (- group 2) по $2


Ok ну, как вы видите в приведенных выше примерах, строка является динамической, но она соответствует константе nt pattern ... Теперь я хочу знать, как создать динамическую группу захвата в соответствии со строкой?

+2

Почему группы захвата? 'preg_match_all ('/ -. * /', $ str, $ matches);' – AbraCadaver

+0

Время от времени возникает этот вопрос. Для каждой группы захвата в PHP PCRE regex нет стека. Используйте несколько совпадений, как показано выше. Всегда есть способы обойти это ограничение. –

+0

Duh, может быть, вы делаете замены ... – AbraCadaver

ответ

1

невозможность захватить повторяющиеся группы является well known limitation.

Если вы знаете максимальный повторяющийся рисунок, вы можете установить регулярное выражение в (то есть макс = 5):

/(\-\s\w+)\n(\-\s\w+)?\n?(\-\s\w+)?\n?(\-\s\w+)?\n?(\-\s\w+)?\n?/ 

и вы найдете от одного до пяти матчей в группах от 1 до 5.
По существу, вы должны повторить (\-\s\w+)?\n? для максимально возможного числа повторяющихся рисунков.

В противном случае, если максимальное возможное число не определено, я не знаю другого пути, чем построить динамическую картину, как:

$regex = '(\-\s\w+)\n'; 
$regex = '/'.(str_repeat($regex, preg_match_all("/$regex/", $str, $matches))).'/'; 

Приведенный выше шаблон будет работает, но я не знаю ваш точно замените условие, поэтому оно может быть непригодным для вашей цели.

+0

Очень хорошая идея этого 'str_repeat' с возвращаемым значением' preg_match_all' (не зная, чего фактически хочет достичь OP). [Играется с ним немного] (https://eval.in/522066) :) –

1

Использование m-модификатора (многострочный): это позволит совпадению на каждой строке.

Попробуйте использовать ниже регулярное выражение:

preg_match_all('/(\-\s\w+)/m', $str, $matches); 
print_r($matches); 
+0

Хороший ответ, но отсутствует '' '. –

+0

Хорошо, но не полезно. Прочтите комментарии, чтобы понять, что OP хочет делать. –

Смежные вопросы