The easiest way to solve this problem is to use the "cascade descent" method.
Its essence is incredibly simple:
The first regular expression we isolate a large piece of text. In this case, it is any text from [
to ]
. The first regular expression will be:
/\[[^\]]*\]/s
that is, any text inside [...]
The second regular expression is applied to the found text, which will find the desired result. In this case it is
/\bStr\d+\b/
Slightly changed the expression from the question, adding a word boundary, because I think this is the right move.
The final code is:
$text = "abcd [abc Str1 def Str2 ghi Str3 ] efg Str4 [Str5 abc Str6 d] hi"; $re1 = "/\\[[^\\]]*\\]/s"; $re2 = "/\\bStr\\d+\\b/"; preg_match_all( $re1, $text, $arr1 ); foreach ( $arr1[0] as $k=>$v ) { preg_match_all( $re2, $v, $arr2 ); // обработка результата, например так: var_dump( $arr2[0] ); };
http://ideone.com/i1qqcr
There are other ways to solve the problem, but they are not so simple.
I highly recommend the "cascade descent" if your knowledge in regular expressions is weak.
Option 2.
The result is obtained with "detachment from the context", that is, you cannot process Str1-3 and Str5-6 as a single coherent whole:
https://ru.stackoverflow.com/a/448588/481
Option 3.
Result with callback. It uses replace, but we know that you can do anything in a callback, for example, to process the received data:
https://ru.stackoverflow.com/a/489561/481
Option 4.
Will not work in PHP, due to the use of unsupported functionality:
(?<=\[[^\[\]]*\bStr\d+\b(?=[^\[\]]*\])