Lunes, 15 de Marzo de 2010
admin
A veces tenemos la necesidad de reemplazar un texto dentro de una cadena larga. Por ejemplo, el uso principal que le doy a esta función es el procesamiento de plantillas para páginas web, en donde tengo la página en HTML puro por un lado, y en su interior hay ciertas palabras clave, por ejemplo —seccionA—, —fotoUsuario—, —menuSesion—, etc; y en la web definitiva, aparecerá otra cosa en lugar de ese texto, aparecerá el objeto al que hace referencia.
Aunque cada cadena de texto seccionA, fotoUsuario, requiere un procesamiento distinto y es posible que no tengamos por qué procesar siempre todas las equivalencias de todos los textos. Queremos en definitiva reemplazar —seccionA— por el resultado de una función que ejecutaremos cuando encontremos ese texto. Sería como:
1 2 3 4
| $disparadores=array("---seccionA---", "---fotoUsuario---", "---menuSesion---");
$reemplazos=array(dibuja_seccionA (), get_fotoUsuario (), dibuja_menuSesion );
$web=str_replace($disparadores, $reemplazos, $web); |
Aunque, como dijimos, en el ejemplo anterior, se tienen que ejecutar dibuja_seccionA(), get_fotoUsuario() y dibuja_menuSesion().
Pero podemos aprovecharnos de las expresiones regulares, para extraer texto que esté entre “—” y “—” y pasar lo que hay entre medias a otra función que decidirá qué hacer; eso hace preg_replace_callback().
1 2 3 4 5 6 7 8 9 10
| function quehacer ($texto)
{
switch ($texto[1]) // [0] devuelve: ---texto---, [1] devuelve texto
{
case 'seccionA': return dibuja_seccionA ();
case 'fotoUsuario': return get_fotoUsuario ();
case 'menuSesion': return dibuja_menuSesion ();
}
}
$web=preg_replace_callback('/---([a-zA-Z0-9_]*)---/', 'quehacer', $web); |
Hasta aquí bien, el primer parámetro es una expresión regular (es un tema muuuy extenso), el segundo es la función a la que llamamos cuando encontramos el texto, y el tercero es de dónde lo sacamos. Bueno, ahora surge un problema, imaginad que necesito pasarle parámetros a esa función callback. Lo podemos hacer así:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| function guardar_datos ($data=null)
{
static $guardados; // Una variable estática, muy importante
// Si se especifica $data, lo guardamos en $guardados, al ser estática, aunque salgamos de la función, el valor de la variable no se perderá.
if ($data)
$guardados=$data;
return $guardados;
}
function quehacer ($texto)
{
$datos = guardar_datos ();
switch ($texto[1]) // [0] devuelve: ---texto---, [1] devuelve texto
{
case 'seccionA': return dibuja_seccionA ();
case 'fotoUsuario': return get_fotoUsuario ($datos);
case 'menuSesion': return dibuja_menuSesion ($datos);
}
}
guardar_datos (array($datos_usuario, $datos_sesion));
$web=preg_replace_callback('/---([a-zA-Z0-9_]*)---/', 'quehacer', $web); |
Nota: las variables $datos_usuario, $datos_sesion y $web no están definidas, como esto es parte de un programa, hay que imaginar un poco cuál será la información que contendrán.
Miércoles, 10 de Marzo de 2010
admin
A mi entender, es una de las funciones más útiles que se han inventado, como programador de PHP estoy harto de utilizarlo para filtrar información (caracteres a la derecha y a la izquierda, ya sean espacios, caracteres especiales o algún carácter que yo utilice para el control de la información).
Sabemos que el usuario final no nos va a dejar las cosas fáciles, puesto que a veces, nos llena un campo con “intros” al principio y al final; o la información, después de pasar por HTTP, lectura de un archivo XML o por otros tratamientos, tal vez tenga un retorno de carro al final; por eso, a veces es útil hacer:
Pero ahora estamos en C++, bien quería postear también el código en C++, así que decidí googlear un poco para ver esto:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #include <string>
const std::string whiteSpaces( " \f\n\r\t\v" );
void trimRight( std::string& str,
const std::string& trimChars = whiteSpaces )
{
std::string::size_type pos = str.find_last_not_of( trimChars );
str.erase( pos + 1 );
}
void trimLeft( std::string& str,
const std::string& trimChars = whiteSpaces )
{
std::string::size_type pos = str.find_first_not_of( trimChars );
str.erase( 0, pos );
}
void trim( std::string& str, const std::string& trimChars = whiteSpaces )
{
trimRight( str, trimChars );
trimLeft( str, trimChars );
} |
Con esto podemos jugar con nuestros textos…
Ahora vamos al caso de C, muchos se siguen preguntando… pero si C es un lenguaje muy antiguo, ¿aún se sigue usando? Pues sí ! Aunque muchas cosas sean horribles de programar en C, a pelo, se sigue usando, y aún le queda mucha vida a este lenguaje. Por eso, veremos dos funciones trim() especiales para C:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| #include <stdio.h>
#include <string.h>
char *trim (char *s )
{
char *start = s ;
/* Nos comemos los espacios al inicio */
while(*start && isspace (*start ))
++start ;
char *i = start ;
char *end = start ;
/* Nos comemos los espacios al final */
while(*i )
{
if( !isspace (*(i ++)) )
end = i ;
}
/* Escribimos el terminados */
*end = 0;
return start ;
}
char *trim2 (char *s , const char *trimChars )
{
char *start = s ;
/* Nos comemos los caracteres al principio */
while(*start && strpbrk ((const char*)start , trimChars )==start )
++start ;
char *i = start ;
char *end = start ;
/* Nos comemos los caracteres al final */
while(*i )
{
if( strpbrk (i ++, trimChars )!=i -1 )
end = i ;
}
/* Coloramos el perminador */
*end = 0;
return start ;
}
int main ()
{
char mi_cadena [30]="\f\n Cadena; \tSucia \n\t ;";
printf("Mi cadena inicialmente: \"%s\"\n", mi_cadena );
printf("Mi cadena tras trim(): \"%s\"\n", trim (mi_cadena ));
printf("Mi cadena tras trim2(): \"%s\"\n", trim2 (mi_cadena ,";\f\n\t"));
} |
En C también podremos tener nuestro trimleft y nuestro trimright y creo que es fácil sacarlo desde esta función general, ya que *start se mueve indicando el principio de la cadena, y con end, y es ese movimiento (que aunque perdemos algo de memoria) el que hace que se recorte la cadena; además, como buena función de C, perdemos la cadena que inicialmente teníamos.
Últimos comentarios