1

this is some hard, I have solutions for this with srtpos, but it's ugly, I need help to do it with preg_pos or preg_match . I have a string like below:

$text="Some 
[parameter=value\[anoter value|subparam=20] with  or 
[parameter|value\]anoter value|subparam=21|nothing] or 
[parameter=value\[anoter value\]|subparam=22] ";

... I would like to get the following result:

array (
  0 => '=value[anoter value|subparam=20',
  1 => '|value[anoter value|subparam=21|nothing',
  2 => '=value[anoter value]|subparam=22',
)

I mean i know my parameter: [parameter---get this section---] after 'parameter' all text can be to change, and it can contains escaped: bracket - square bracket - parenthesis - ampersand. thanks !

stackdave
  • 5,351
  • 8
  • 32
  • 55

2 Answers2

0

Use \K to discard the previously matched characters.

\[parameter\K(?:\\[\]\[]|[^\[\]])*

DEMO

$re = "~\\[parameter\\K(?:\\\\[\\]\\[]|[^\\[\\]])*~m";
$str = "Some \n[parameter=value\[anoter value|subparam=20] with or \n[parameter|value\]anoter value|subparam=21|nothing] or \n[parameter=value\[anoter value\]|subparam=22] \";\nfoo bar";
preg_match_all($re, $str, $matches);
print_r($matches);

Output:

Array
(
    [0] => Array
        (
            [0] => =value\[anoter value|subparam=20
            [1] => |value\]anoter value|subparam=21|nothing
            [2] => =value\[anoter value\]|subparam=22
        )

)
Avinash Raj
  • 160,498
  • 22
  • 182
  • 229
  • sorry I can't check the 2 replies, both are correct ! – stackdave Feb 08 '15 at 16:22
  • difference between me and jhonny's is , i added `parameter` in the regex but he uses `\w+` and the another thing is, i escaped all the brackets which are inside the character class to avoid confusion but he properly placed the brackets without escaping. The reason for why i added parameter string is because of `I mean i know my parameter: ` string in your question.. – Avinash Raj Feb 08 '15 at 16:28
  • i did it Avinash, but stackoverflow only took me the last click. thanks – stackdave Feb 18 '15 at 22:13
0

Even if you extract the substrings you are interested by, you will need to remove the escaped square brackets in a second time. Let's see the full solution:

$pattern = '~\[\w+\K[^]\\\]*(?:(?:\\\.)+[^]\\\]*)*+(?=])~s';

if (preg_match_all($pattern, $str, $m))
    $result = array_map(function ($item) {
        return strtr($item, array('\]' => ']', '\[' => '['));
    }, $m[0]);
Casimir et Hippolyte
  • 83,228
  • 5
  • 85
  • 113