Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create a dynamic capturing group in regex?

Tags:

string

regex

php

I have a string like this:

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

Also I have this regex:

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

As you know, there is three capturing groups: $1, $2 and $3. I made those group manually. I mean if I append this to the string above:

- group4 
- group5

Then that regex doesn't matches them.


Well, I have a constant pattern: (\-\s\w+), And I want to create a separated capturing group on the number of matches items in the string. Hare is a few examples:

Example1:

$str="
- group 1
";

I need a regex to give me all the string by $1.


Example2:

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

I need a regex to give me first line of string (- group 1) by $1 and second line (- group 2) by $2


Ok well, as you see in the examples above, string is dynamic but it is according to a constant pattern ... Now I want to know how can I create a dynamic capturing group according to the string?

like image 492
Shafizadeh Avatar asked Feb 19 '16 18:02

Shafizadeh


2 Answers

The impossibility to capture repeating groups is a well known limitation.

If you know the max repeating pattern, you can set your regex as (i.e. max=5):

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

and you will find from one to five matches in the groups from 1 to 5.
Substantially, you have to repeat (\-\s\w+)?\n? for the max possible number of repeating pattern.

Otherwise, if your max possible number is undefined, I don't know other way than construct a dynamic pattern, as:

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

The above pattern will works, but I don't know your exactly replace condition, so it can be unusable for your purpose.

like image 191
fusion3k Avatar answered Nov 07 '22 18:11

fusion3k


Using the m-modifier (multi-line): that will let the match on each line.

Try using below regex:

 preg_match_all('/(\-\s\w+)/m', $str, $matches);
 print_r($matches);
like image 21
Sandeep Avatar answered Nov 07 '22 19:11

Sandeep