T
The idea is first to check if the tag has the same value as the array, and make the substitution accordingly.If the value is the same as the array, I only remove the tags and keep the text between them. Otherwise, I remove everything (tags and text):function remove($texto, $array, $tag) {
$opcao = $array[$tag];
// se a tag tem o mesmo valor do array
if (preg_match("/\{$tag=$opcao\}/", $texto)) {
$replace = '$1'; // substitui pelo texto entre as tags
} else { // senão, remove tudo
$replace = '';
$opcao = '[^}]+';
}
$regex = "/\{$tag=$opcao\}([^{]+)\{$tag\}/";
return preg_replace($regex, $replace, $texto);
}
$texto = 'Olá, [usuario], seu cadastro foi efetuado em [data_cadastro] {aceitou_termos=sim} ,e você ganhou 1 milhão de reais {aceitou_termos}, seu primeiro nome é [usuario,1] {assinante=nao} assine hoje e ganha 10% de desconto{assinante}';
$array['aceitou_termos'] = 'sim';
$array['assinante'] = 'nao';
$textoFinal = remove($texto, $array, 'aceitou_termos');
$textoFinal = remove($textoFinal, $array, 'assinante');
That is, if you have the tag with the same value of the array, I will replace it with the text between the tags. For this I use [^{]+ (one or more characters other than {). That is, I am assuming that the text between the tags has no {.In case you keep the text, I'll place the passage [^{]+ between parentheses to form a http://regular-expressions.info/brackets.html , so I can get your content later, with $1.If the tag does not have the same value, I remove everything (do the replace by empty string).If the array contains only the tags and their respective values, a loop for them, and going to change all:function remove($texto, $array, $tag, $opcao) {
if (preg_match("/{$tag=$opcao}/", $texto)) {
$replace = '$1';
} else {
$replace = '';
$opcao = '[^}]+';
}
$regex = "/{$tag=$opcao}([^{]+){$tag}/";
return preg_replace($regex, $replace, $texto);
}
$texto = 'Olá, [usuario], seu cadastro foi efetuado em [data_cadastro] {aceitou_termos=sim} ,e você ganhou 1 milhão de reais {aceitou_termos}, seu primeiro nome é [usuario,1] {assinante=nao} assine hoje e ganha 10% de desconto{assinante}. {obs=sim}Obs: etc blabla{obs}';
$array = [
'aceitou_termos' => 'sim',
'assinante' => 'nao',
'obs' => 'sim'
];
$textoFinal = $texto;
foreach ($array as $tag => $opcao) {
$textoFinal = remove($textoFinal, $array, $tag, $opcao);
}
echo $textoFinal;
If the tags exist more than once in the text, then it's a bit more boring (and inefficient, maybe it's better https://stackoverflow.com/questions/1440480/how-to-write-an-antlr-parser-for-jsp-asp-php-like-languages ), because you have to check each occurrence of the tag, check if the value is equal to that of the array and make the replacement:function remove($texto, $array, $tag, $opcao) {
while (preg_match("/{$tag=([^}]+)}/", $texto, $matches)) {
if ($matches[1] == $opcao) {
$replace = '$1';
$opt = $opcao;
} else {
$replace = '';
$opt = '[^}]+';
}
$regex = "/{$tag=$opt}([^{]+){$tag}/";
$texto = preg_replace($regex, $replace, $texto, 1);
}
return $texto;
}
$texto = 'Olá {aceitou_termos=sim}aceitou termos {aceitou_termos}bla bla etc {assinante=nao}não assinou{assinante} xyz{aceitou_termos=nao} não aceitou{aceitou_termos}.';
$array = [
'aceitou_termos' => 'sim',
'assinante' => 'nao'
];
$textoFinal = $texto;
foreach ($array as $tag => $opcao) {
$textoFinal = remove($textoFinal, $array, $tag, $opcao);
}
echo $textoFinal;
That is, while you have the tag, check if the value is equal to that of the array and make the substitution accordingly (or remove everything, or keep the text between the tags).In the case, if aceitou_termos for "yes", the result will be:Olá aceitou termos bla bla etc não assinou xyz.
And if aceitou_termos for "no", the result will be:Olá bla bla etc não assinou xyz não aceitou.
The rest of the answer below is for https://pt.stackoverflow.com/revisions/474682/1 , which I think may be useful to those interested.I don't think I need regex. If you only have a tag occurrence {aceitou_termos}, can only do with https://www.php.net/manual/en/function.strpos.php and https://www.php.net/manual/en/function.substr.php :$texto = 'Olá, [usuario], seu cadastro foi efetuado em [data_cadastro]{aceitou_termos}, e você ganhou 1 milhão de reais {aceitou_termos}, seu primeiro nome é [usuario,1]';
$array['aceitou_termos'] = 'sim';
$tag = '{aceitou_termos}';
$len = strlen($tag);
$inicioTag = strpos($texto, $tag); // primeira ocorrência da tag
$fimTag = strpos($texto, $tag, $inicioTag + $len); // segunda ocorrência da tag
$textoFinal = substr($texto, 0, $inicioTag); // pega do início até a primeira ocorrência da tag
if ($array['aceitou_termos'] == 'sim') { // pega o texto entre as tags
$textoFinal .= substr($texto, $inicioTag + $len, $fimTag - $inicioTag - $len);
}
$textoFinal .= substr($texto, $fimTag + $len); // pega da segunda ocorrência da tag até o final da string
echo $textoFinal;
That is, I take the positions of the first and last occurrence of the tag, and see if what is between them should be concatenated or not.But of course you can do with regex:$texto = 'Olá, [usuario], seu cadastro foi efetuado em [data_cadastro]{aceitou_termos}, e você ganhou 1 milhão de reais {aceitou_termos}, seu primeiro nome é [usuario,1]';
if ($array['aceitou_termos'] == 'sim') {
// sim, basta remover as tags
$textoFinal = str_replace('{aceitou_termos}', '', $texto);
} else {
// remove as tags e o texto entre elas
$textoFinal = preg_replace('/{aceitou_termos}[^{]+{aceitou_termos}/', '', $texto);
}
echo $textoFinal;
Even though you have less lines, is it easier? It is relative, but anyway, the idea is to catch the tags themselves (and the brackets should be escaped with </code>), and between them I use [^{]+ (one or more characters other than {). That is, I am assuming that the text between the tags has no {.Note that if you have to include the text between the tags, just remove the tags themselves using one replace simple (no regex).In the second case, it would be like this:// se for "nao", remove tudo entre as tags
$textoFinal = preg_replace('/{aceitou_termos=nao}[^{]+{aceitou_termos}/', '', $texto);
// se for "sim", mantém o texto entre as tags
$textoFinal = preg_replace('/{aceitou_termos=sim}([^{]+){aceitou_termos}/', '$1', $textoFinal);
The description of the question seems to me that it is on the contrary, since it says it should display the text if it is {aceitou_termos=nao}, but I understand that the text should only be displayed if it is {aceitou_termos=sim} (but if not, just reverse the "yes" and "no" in the above code).In case you keep the text, I'll place the passage [^{]+ between parentheses to form a http://regular-expressions.info/brackets.html , so I can get your content later, with $1.