I am using preg_replace_callback
to replace the results of patterns that are in $regexList
.
The problem is that this function takes the occurrence of the first pattern in $regexList
, instead of taking the first occurrence in $string
that has a pattern in $regexList
. / p>
Use only a regex.
In this case, do not use an array. Instead:
$regexList = [
'/regex1/',
'/regex2/',
'/regex3/',
];
Use this:
$regex = '/regex1|regex2|regex3/';
In function:
$resultado = preg_replace_callback(
$regex,
function ($matches) {
// ...
return 'substituído';
},
$texto
);
But how do you know which regex was found?
You can use groups to identify them.
$regex = '/(regex1)|(regex2)|(regex3)/';
Then:
$resultado = preg_replace_callback(
$regex,
function ($matches) {
if ($matches[1]) {
return 'regex1 substituído';
} else if ($matches[2]) {
return 'regex2 substituído';
} else if ($matches[3]) {
return 'regex3 substituído';
}
},
$texto
);
But you have other groups in the patterns, and counting the right group number can be tricky. We can use named groups to make things easier.
$regex = '/(?P<padrao1>regex1)|(?P<padrao2>regex2)|(?P<padrao3>regex3)/';
$resultado = preg_replace_callback(
$regex,
function ($matches) {
if ($matches['padrao1']) {
return 'regex1 substituído';
} else if ($matches['padrao2']) {
return 'regex2 substituído';
} else if ($matches['padrao3']) {
return 'regex3 substituído';
}
},
$texto
);
Code
To answer your question, with a little recursion:
function analisar( $string ) {
$regex = '/
(?P<var> {{\s*\$(.*?)\s*}} )
|
(?P<loop> @for\((.*?)\)\s*{{((?:[^{}]|(?R))*)}} )
|
(?P<statement> @if\((.*?)\)\s*{{((?:[^{}]|(?R))*)}} )
/x';
$resultado = preg_replace_callback(
$regex,
function ($matches) {
/*
//debug
echo "\n\nSubst: $matches[0]\n\$matches = ";
var_export($matches);
*/
if ($matches['var']) {
return getVar($matches[2]);
} else if ($matches['loop']) {
return loop($matches[4], $matches[5]);
} else if ($matches['statement']) {
return getStatementResult($matches[7], $matches[8]);
}
},
$string
);
return $resultado;
}
function getVar($nomeDaVariavel){
return 'VAR('
. analisar($nomeDaVariavel)
. ')';
}
function loop($nomeDoArray, $codigo){
return "LOOP\nLOOP-COND("
. analisar($nomeDoArray)
. ")\nLOOP-CODIGO("
. analisar($codigo)
. ')';
}
function getStatementResult($expressãoBooleana, $codigo){
return "IF\nIF-COND("
. analisar($expressãoBooleana)
. ")\nIF-CODIGO("
. analisar($codigo)
. ')';
}
Test:
$string = '
<span>{{ $nomeCompleto }}</span>
@for($nomes as $nome)
{{
@if($nome == \'Eleandro\')
{{
<p>{{ $nome }}</p>
}}
}}
';
echo analisar($string);
Result:
<span>VAR(nomeCompleto)</span>
LOOP
LOOP-COND($nomes as $nome)
LOOP-CODIGO(
IF
IF-COND($nome == 'Eleandro')
IF-CODIGO(
<p>VAR(nome)</p>
)
)
Demo: link