You need to use a recursive pattern, example:
$pattern = '~{((?>[^{}]++|(?R))*)}~';
Where (?R)
stands for all the pattern (the whole pattern repeated inside itself)
Вопрос
If I have a string like below:
$str = "Some {translate:text} with some {if:{isCool}?{translate:cool}|{translate:uncool}} features";
... I would like to get the following result:
array (
0 => 'translate:text',
1 => 'if:{isCool}?{translate:cool}|{translate:uncool}',
)
I already have this function but i belive its possible to simplify it with preg_match(_all)?
define('STR_START','{');
define('STR_END','}');
function getMarkers($str, &$arr = array()) {
if(strpos($str,STR_START)) {
list($trash,$str) = explode(STR_START,$str, 2);
unset($trash);
$startPos = 0;
$endPos = 0;
do {
$strStartPos = strpos($str,STR_START,$startPos);
$strEndPos = strpos($str,STR_END,$endPos);
$startPos = $strStartPos + 1;
$endPos = $strEndPos + 1;
} while($strStartPos !== false && $strStartPos < $strEndPos);
$arr[] = substr($str,0,$strEndPos);
getMarkers(substr($str,$strEndPos+1),$arr);
}
return $arr;
}
I have tried the following but it dose not work that well with submarkers.
preg_match_all('/\{(.*?)\}/',"Some {translate:text} with some {if:{isCool}?{translate:cool}|{translate:uncool}} features", $matches);
var_export($matches[1]);
array (
0 => 'translate:text',
1 => 'if:{isCool',
2 => 'translate:cool',
3 => 'translate:uncool',
)
Is it possible to ajust the abowe mentioned pattern to get the right result?
array (
0 => 'translate:text',
1 => 'if:{isCool}?{translate:cool}|{translate:uncool}',
)
Решение
You need to use a recursive pattern, example:
$pattern = '~{((?>[^{}]++|(?R))*)}~';
Where (?R)
stands for all the pattern (the whole pattern repeated inside itself)