Eliminar tildes, eñes y caracteres raros con Javascript

03 Mar 2011

Los desarrolladores de aplicaciones Javascript a menudo tenemos que pelearnos con cadenas de texto llenas de tildes, eñes y otros caracteres raros como diéresis o cerillas (ç). Por ejemplo, son frecuentes cuando recogemos datos de formularios o cuando tenemos que obtener URLs válidas a partir del titular de una noticia.

Este pequeño snippet resulta muy útil para sustituir esos caracteres devolviendo cadenas limpias y seguras:

var normalize = (function() {
  var from = "ÃÀÁÄÂÈÉËÊÌÍÏÎÒÓÖÔÙÚÜÛãàáäâèéëêìíïîòóöôùúüûÑñÇç", 
      to   = "AAAAAEEEEIIIIOOOOUUUUaaaaaeeeeiiiioooouuuunncc",
      mapping = {};
 
  for(var i = 0, j = from.length; i < j; i++ )
      mapping[ from.charAt( i ) ] = to.charAt( i );
 
  return function( str ) {
      var ret = [];
      for( var i = 0, j = str.length; i < j; i++ ) {
          var c = str.charAt( i );
          if( mapping.hasOwnProperty( str.charAt( i ) ) )
              ret.push( mapping[ c ] );
          else
              ret.push( c );
      }      
      return ret.join( '' );
  }
 
})();


La probamos:

console.log( normalize('Fábula de la cigüeña y el murciélago') );
// Fabula de la ciguena y el murcielago

Bonus: formateando URLs

Si queremos formatear la cadena resultante con un estilo optimizado para URLs (cambiando los espacios por guiones bajos), sólo tenemos que modificar una línea de código:

En lugar de

return ret.join( '' );

Escribimos

return ret.join( '' ).replace( /[^-A-Za-z0-9]+/g, '-' ).toLowerCase();

Y obtendríamos lo siguiente:

console.log( 'Fábula de la cigüeña y el murciélago' ); 
// fabula-de-la-ciguena-y-el-murcielago

Y eso es todo; ya podemos estar seguros de que no convertiremos en URLs cadenas raras o que no metemos en la base de datos textos con caracteres no permitidos.

Más:

{13} Comentarios.

  1. Cristhian Diaz

    Gracias por el Script, muy útil ya lo estoy usando.

  2. Edward

    buenisimo el ejemplo, gracias!!!

  3. Joaquín

    Si se utiliza este snippet en un documento que cargue el editor TinyMCE, provocará errores: Parece que el nombre de la variable «normalize» ya se utiliza en alguna función interna de TinyMCE y por tanto tu snippet entra en conflicto con ella.

    Bueno, sólo este pequeño aporte. Para que otro webmaster no pierda el tiempo que yo he tenido que invertir en por qué no funcionaba…

  4. Ieeep! gran aporte, me has ahorrado teclear código!

    Un saludo,

  5. Revisando el código… tengo curiosidad por una cosa.

    Por qué la función está definida así?

    Por mi parte he revisado la función y la he intentando declarar de forma «clásica» con la composición de «function algo(){};» pero esta no me ha dado ningún efecto… siendo tu forma de definición la única que me funciona.

    También me parece curioso el doble return… no sería igual recorrer el string desde la función principal y no declarar otra en desde el return?

    Y por último el «()» final de la función que indica? que es autoejecutable?

    Pregunto por aprender! ya que me ha encantado esta forma de definición!

    Un saludo,

    • Carlos Benítez

      Hola!
      Si; se trata de una función autoejecutable que a su vez devuelve otra función (el primer return). Esa nueva función, que es la encargada de procesar la cadena, tiene su propio contexto (scope) quedando el global ‘más limpio’. Es un patrón de tipo módulo, muy escalable, organizado y siempre recomendable. Las funciones ‘sueltas’ contaminan demasiado el espacio global, por lo que suelen evitarse en los desarrollos modernos.

      Se podría ‘convertir’ a una forma clásica como la que sugieres, pero quedaría menos bonita.

      Puedes ver más sobre este tema aquí:
      Funciones autoejecutables en Javascript

      Saludos!

  6. Francisco

    Es muy curioso esto.

    Me encuentro probando la API de Open Libra y dado a que no soy muy dicho en JavaScript me ha costado bastante crear la parte cuando quería crear el enlace al libro que se muestra.

    Pasé tiempo buscando como cambiar la ñ y los espacios, y justo cuando busco para palabras acentuadas, llego aquí. Al sitio del creador de la API y de Open Libra.

    Sirvió a mil! Ya tengo un mini MVP de la aplicación que consume la API de Open Libra!

  7. Jackson Echeverri

    Muy bueno y muy útil.

    Muchas gracias por compartirlo.

  8. Fernando Magrosoto

    Me pareció extraordinario este snippet. Muy sencillo y súper necesario.
    Lo voy a subir a GitHub con tus créditos.
    Gracias Carlos.
    Saludos

  9. Simon

    Muy bueno muchas gracias

  10. Rodrigo Zeta

    Hola!

    Muchas gracias por la idea. En base a tu script, lo dejé más compacto.
    Saludos.

    function normalizar(s) {
    var s1 = ‘ÃÀÁÄÂÈÉËÊÌÍÏÎÒÓÖÔÙÚÜÛãàáäâèéëêìíïîòóöôùúüûÑñÇç’;
    var s2 = ‘AAAAAEEEEIIIIOOOOUUUUaaaaaeeeeiiiioooouuuunncc’;
    for (var i = 0; i < s1.length; i++) s = s.replace(new RegExp(s1.charAt(i), 'g'), s2.charAt(i));
    return s;
    }

    console.log(normalizar('Fábula de la cigüeña y el murciélago'));

  11. ivan

    gracias viejo!

  12. Jairo

    Muy bueno… muchas gracias por compartir, saludos desde Panamá

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *