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"; ?>