Publicidad

martes, 24 de abril de 2007

Crear un modificador de caracteres en php

"Sólo los estúpidos son esclavos del tiempo y el espacio"

Lost


Hoy en Malditaseamanía vamos a aprender a crear un modificador de caracteres en php. ¿Qué es un modificador de caracteres? Bueno, es un nombre ficticio para una función muy graciosa de PHP que se utiliza, normalmente, para censurar palabras en foros y blogs. Es muy graciosa y muy útil, sobretodo para evitar mensajes como el siguiente:

HOYGAN! IJOSDEPUTA DEL VLOGUERO K ME KAGO EN SUS PUTAKAS MADRES DEL HAMOR ERMOSO NO ME DIGAN K NO LE GUSTA LO K DIGO K ME KIER CNSURAR PUTA MIERDA. SCRIVES DE PENA Y DEVERIAN DE HARRANCART LA PLBIS A PATAS. CHUPAMELNAVAKO.


Bueno, aunque mensajes como ese requerirían algo más que una simple función phpera para evitarlos. Vamos al asunto.

El meollo de la cuestión


¿Cómo hacer para cambiar unos caracteres por otros? Ya sea por la función que se quiera. Para eso nada mejor que un ejemplo. En el siguiente ejemplo, vamos a cambiar todas las letras p por la palabra pene. Vale, es el caso inverso a nuestro censurador de palabras, pero para aprender igualmente nos vale.


  1. En primer lugar vamos a definir tres variables: $patron, $texto y $encontrado.

    $patron, en este caso, será un caracter, aunque también puede usarse como cadena de caracteres. Será la palabra/caracter que queremos cambiar estando éste entre comillas y barras: ("/{ejemplo}/"). Lo llamamos así porque será nuestro patrón de búsqueda.

    $texto será el mensaje sobre el que queremos cambiar cada p por pene.

    $encontrado será un booleano que nos indicará si encuentra la palabra/caracter buscada o no usando una función en php que los busca: preg_match_all. No profundizaremos en este punto y dejaremos que el lector copie y pegue como mejor pueda. Esta función utilizará cuatro valores(por orden de uso): $patron (patrón de búsqueda, puede ser una cadena de caracteres); $texto (texto en el que buscar el patrón); $coincidencias (devuelve el valor TRUE o FALSE al valor de $encontrado); y PREG_OFFSET_CAPTURE(una cosa muy chunga que nos ayudará en nuestro código).

    Por ejemplo, para el caso que tratamos, el código sería:
    $patron = "/p/";
    $encontrado = preg_match_all($patron, $texto, $coincidencias, PREG_OFFSET_CAPTURE);


  2. Ahora generamos un análisis de casos (una expresión if) que se active en el caso de que exista un caracter 'p' en la variable $texto. De esta forma, hacemos que la web vaya más rápida y optimizamos el código. Seguidamente generamos cuatro nuevas variables: $patron2,$ch, y dos contadores $index y $index2.

    En este caso, $patron2 y $ch tienen funciones equivalentes. $patron2 cogerá el valor de $texto para analizarlo. Esta variable no es necesaria, pero yo la declararía por si luego añadiésemos más funciones en las que requiriésemos el texto original. $ch, en cambio, irá generando la nueva palabra. Como la longitud del array va a aumentar, parece lógico hacer un contador de array para el texto y otro para la nueva palabra más larga. Ambos contadores los inicializamos (aunque no sea realmente necesario) por si los hubiésemos utilizado anteriormente y guardasen un valor que se cargase nuestro código.

    El análisis de casos quedaría, finalmente, algo así:
    if ($encontrado) {
    $patron2 = $texto;
    $ch = $texto;
    $index = 0;
    $index2 = 0;
    }

  3. Utilizando las variables declaradas, finalmente, añadimos un bucle, concretamente una función for. A la misma le daremos datos sobre qué evaluar, la condición de parada y haremos que vaya aumentando el index con cada for. Dentro de esta función, haremos que $ch[$index2] vaya cogiendo el valor actual de $patron2[$index], luego analizamos si el valor $ch ha adquirido el valor 'p' y, si es así, generamos un código que le vaya dando los valores. Para saber si $ch ha cogido el valor 'p', utilizaremos la función strcasecamp que compara dos cadenas de caracteres y da, como valor, la diferencia entre ambos. Finalmente, aumentamos el contador $index2 en una unidad.

    Parece complicado, pero todo queda bien resumido con el siguiente código:
    for($index; $index < strlen($patron2); $index++)
    {
    $ch[$index2] = $patron2[$index];
    if (strcasecmp($ch[$index2], "p") == 0) {
    $index2++;
    $ch[$index2] = "e";
    $index2++;
    $ch[$index2] = "n";
    $index2++;
    $ch[$index2] = "e";
    }
    $index2++;
    }


El código resultante para cambiar el caracter 'p' por el array de carecteres 'pene' es:

$patron = "/p/";
$encontrado = preg_match_all($patron, $texto, $coincidencias, PREG_OFFSET_CAPTURE);
if ($encontrado) {
$patron2 = $texto;
$ch = $texto;
$index = 0;
$index2 = 0;
for($index; $index < strlen($patron2); $index++){
$ch[$index2] = $patron2[$index];
if (strcasecmp($ch[$index2], "p") == 0) {
$index2++;
$ch[$index2] = "e";
$index2++;
$ch[$index2] = "n";
$index2++;
$ch[$index2] = "e";
}
$index2++;
}
$texto = $ch;
}


Espero que este código os sirva para algo. Si lo que queréis hacer es cambiar palabras por lo que sea todo va igual, sólo que habría que hacer un nuevo loop y una nueva variable que fuese palabra por palabra (generando una nueva función para esto por comodidad) necesitando una nueva variable que fuese cogiendo la palabra y usándola para evaluar con el patrón. Es fácil, pero de todas formas ya la haré para otra ocasión.

1 comentario:

Anónimo dijo...

sabes que simplemente necesitas una sola funcion?

$mensaje = str_replace("p","pen*",$mensaje);