El código maneja cadenas... La idea es hacer un sistema de plantillas pero algo complejas, como las de Smarty.
Básicamente en mi template tendría variables y funciones de plantilla, por ej:
Una variable sería: {variable_name}
La variable también podría tener modificador, {variable_name|modificador} nótese el "|" luego del nombre de la variable
Y las funciones serían algo como {function_name file="my_file" title="my title"} nótese que luego del nombre de la función va un espacio en blanco y luego la lista de parámetros...
Bien. Para no complicar el ejemplo voy solamente a dividir tanto las variables como las funciones en 2 partes: nombre y argumentos|modificadores... El código que voy a exponer simplemente debería extraer el nombre de la variable o de la funcion, validando que la misma sea correcta (no contenga caracteres inválidos, etc) y por otro lado va a extrar la otra parte sin procesarla ni validarla.
Para ello partiré de un punto ficticio donde tengo un array con todas las variables o funciones de mi plantilla sin delimitadores, es decir sin las llaves a los lados.
Ah, casi lo olvido... las variables pueden estar dividas en segmentos así: segmento1.segmento2.segmento3 (nótese los puntos ".") Y tanto funciones como variables o segmentos deben empezar con una letra, y tener sólo letras, números y guion bajo
Según mi pc y el método
Bien... Aquí ambos códigos:
Sin REGEX
Código PHP :
<?php
$tiempo_inicio = microtime(true);
/***/
$strings = array
(
'contact.phone.home|truncate:30:"..."',
'include_tpl file="test" title="another test" test=1 var_test=contact.phone.home|truncate',
'contact.phone.home',
'cristalab',
'clab',
'love4clab',
'freddie',
'ramm',
'dano',
'maik',
'google',
'youtube',
'facebook',
'dessigual.com',
'word_with_09_numbers',
'word_with_underscore',
'simply',
'dummy',
'text',
'printing',
'typesetting',
'industry'
);
foreach($strings as $string)
{
$n = strlen($string);
$mustBeAlpha = true;
$isVar = false;
$name = '';
$varName = '';
$functionName = '';
$i = 0;
for(; $i < $n; $i ++)
{
$l = $string[$i];
if($mustBeAlpha)
{
if(ctype_alpha($l))
{
$name .= $l;
$mustBeAlpha = false;
}
else
{
die("Nombre de variable/funcion invalida: <strong>$string</strong>");
}
}
else if(ctype_alnum($l) || ($l == '_'))
{
$name .= $l;
}
else if($l == '.')
{
$name .= $l;
$isVar = true;
$mustBeAlpha = true;
}
else if($l == '|')
{
$varName = $name;
break;
}
else if($l == ' ')
{
if($isVar)
{
die("Nombre de variable/funcion invalida: <strong>$string</strong>");
}
$functionName = $name;
break;
}
else
{
die("Nombre de variable/funcion invalida: <strong>$string</strong>");
}
}
if($name[$i - 1] == '.')
{
die('Nombre de variable/funcion invalida');
}
if($i < $n)
{
$arguments = substr($string, $i + 1);
}
else
{
$arguments = '';
}
if($functionName != '')
{
echo "Function name: $name --- ";
echo "Arguments: $arguments";
}
else
{
echo "Varname: $name --- ";
echo "Modifiers: $arguments";
}
echo "<br />\n";
}
/***/
$tiempo_final = microtime(true);
$tiempo = $tiempo_final - $tiempo_inicio;
echo "<br />\nTotal: $tiempo segundos\n";
?>
Con REGEX:
Código PHP :
<?php
$tiempo_inicio = microtime(true);
/***/
$strings = array
(
'contact.phone.home|truncate:30:"..."',
'include_tpl file="test" title="another test" test=1 var_test=contact.phone.home|truncate',
'contact.phone.home',
'cristalab',
'clab',
'love4clab',
'freddie',
'ramm',
'dano',
'maik',
'google',
'youtube',
'facebook',
'dessigual.com',
'word_with_09_numbers',
'word_with_underscore',
'simply',
'dummy',
'text',
'printing',
'typesetting',
'industry'
);
$namePattern = '[a-z][\w]+';
$varPattern = '/(' . $namePattern . ')(?:( .+)|(?:((?:\.' . $namePattern . ')*)(?:\|(.+))?))?/';
foreach($strings as $string)
{
$functionName = '';
$varName = '';
/*
Var Pattern:
matches:
2 -> name,
3 -> function arguments,
4 -> another part of the name var
5 -> var modifiers
*/
if(preg_match($varPattern, $string, $matches))
{
if(empty($matches[2]))
{
$varName = $matches[1];
if(isset($matches[3]))
{
$varName .= $matches[3];
}
if(isset($matches[4]))
{
$arguments = $matches[4];
}
else
{
$arguments = '';
}
}
else
{
$functionName = $matches[1];
$arguments = $matches[2];
}
}
else
{
die('Nombre de variable/funcion invalida');
}
if($functionName != '')
{
echo "Function name: $functionName --- ";
echo "Arguments: $arguments";
}
else
{
echo "Varname: $varName --- ";
echo "Modifiers: $arguments";
}
echo "<br />\n";
}
/***/
$tiempo_final = microtime(true);
$tiempo = $tiempo_final - $tiempo_inicio;
echo "<br />\nTotal: $tiempo segundos\n";
?>
