2009-11-20 41 views
14

Estoy haciendo un sitio web sueco, y las letras suecas son å, ä, y ö.¿Cómo eliminar signos diacríticos del texto?

Necesito hacer una cadena ingresada por un usuario para convertirse en url-safe con PHP.

Básicamente, necesitamos convertir todos los caracteres que ponen de relieve, todos excepto los siguientes:

A-Z, a-z, 1-9 

y todos sueco debe ser convertido de esta manera:

'A' a 'a' y 'A' a 'a' y 'ö' a 'o' (simplemente elimine los puntos de arriba).

El resto debería convertirse en guiones bajos como ya he dicho.

No soy bueno en expresiones regulares así que agradecería la ayuda chicos!

Gracias

NOTA: No urlencode ... me necesitan almacenar en una base de datos, etc, etc ..., urlencode no trabajará para mí.

Respuesta

13
// normalize data (remove accent marks) using PHP's *intl* extension 
$data = normalizer_normalize($data); 

// replace everything NOT in the sets you specified with an underscore 
$data = preg_replace("#[^A-Za-z1-9]#","_", $data); 
+4

Mencione que 'normalizer_normalize()' es parte de la extensión _intl_ PHP que no siempre está activa. Esta extensión se agregó al núcleo en PHP 5.3, pero en la mayoría de las distribuciones de Linux no está activa por defecto. Por ejemplo, en Debian está en el paquete separado _php5-intl_. Si no puede instalarlo/activarlo, intente _ext/iconv_. en su lugar –

+1

@Mytskine He agregado el comentario. Gracias por señalar eso: estaba en mi defecto para mí, así que no lo pensé ni un segundo. –

4

Si solo está interesado en hacer que la URL de las cosas sea segura, entonces quiere urlencode.

Devuelve una cadena en la que todos los caracteres no alfanuméricos excepto -_. se han reemplazado con un signo de porcentaje (%) seguido de dos dígitos hexadecimales y espacios codificados como signos más (+). Se codifica de la misma manera que datos publicados desde un formulario WWW es codificado, que es la misma manera que en application/x-www-form-urlencoded tipo de medio. Esto difiere de la codificación » RFC 1738 (ver rawurlencode()) en que, por razones históricas, los espacios se codifican como signos más (+).

Si realmente quiere despojar a todos los no AZ, az, 1-9 (? Qué le pasa a 0, por cierto), entonces usted quiere:

$mynewstring = preg_replace('/[^A-Za-z1-9]/', '', $str); 
+0

lo siento, Olvidé mencionar que no necesito urlencode –

+1

Si quieres que sea seguro, entonces quieres urlencode. El hecho de que quiera almacenarlo en una base de datos no está al margen (aparte de eso, querrá escapar de su consulta de inserción de SQL además de hacer que sea seguro para url). – Quentin

+0

Simplemente no entiendes. Quiere que sea seguro usarlo como URL, pero no ESTO seguro. Él preferiría que falle en un espacio o un símbolo. – JohnFx

7

y todos deberíamos sueco ser convertido así:

'å' a 'a' y 'ä' a 'a' y 'ö' a 'o' (simplemente elimine los puntos de arriba).

Use normalizer_normalize() para deshacerse de diacritical marks.

El resto debería ponerse de guión bajo como dije.

Uso preg_replace() con un patrón de [\W] (i.o.w: cualquier carácter que no coincide con letras, dígitos o guión) para sustituirlos por subrayados.

resultado final debe ser similar:

$data = preg_replace('[\W]', '_', normalizer_normalize($data)); 
1

Una solución simple es utilizar str_replace función de búsqueda y reemplazo con matrices de letras.

0

No es necesario expresiones regulares de lujo para filtrar los caracteres suecos, sólo tiene que utilizar el strtr function a "traducir" ellos, como:

$your_URL = "www.mäåö.com"; 
$good_URL = strtr($your_URL, "äåöë etc...", "aaoe etc..."); 
echo $good_URL; 

-> salida: www.maao.com :)

+1

Es solo una pesadilla de mantenimiento cubrir miles de esos personajes conocidos en el mundo de los humanos. – BalusC

2

tan simple como

$str = str_replace(array('å', 'ä', 'ö'), array('a', 'a', 'o'), $str); 
$str = preg_replace('/[^a-z0-9]+/', '_', strtolower($str)); 

suponiendo que se utiliza la misma codificación de sus datos y su código.

+1

'/ [^ a-z0-9] +/i' o '/ [^ A-Za-z0-9] + /' para ignorar el caso –

+0

strtr es más conveniente para "traducir" conjuntos de caracteres, como: $ str = strtr ($ str, "aëïöü", "aeiou"); no usa arrays – danii

+2

Las matrices son difíciles de mantener para mantener un millar de caracteres con marcas diacríticas conocidas en el mundo de los humanos. Solo usa 'normalizer'. – BalusC

18

Uso iconv para convertir cadenas a partir de una determinada codificación a ASCII, a continuación, reemplazar caracteres no alfanuméricos utilizando preg_replace:

$input = 'räksmörgås och köttbullar'; // UTF8 encoded 
$input = iconv('UTF-8', 'ASCII//TRANSLIT', $input); 
$input = preg_replace('/[^a-zA-Z0-9]/', '_', $input); 
echo $input; 

Resultado:

raksmorgas_och_kottbullar 
+1

Debe usar "UTF-8" de esta manera: '$ data = iconv ('UTF-8', 'ASCII // TRANSLIT', $ data);'; de lo contrario, puede encontrar este aviso: "Juego de caracteres incorrecto, conversión de 'UTF8 'a' ASCII // TRANSLIT' no está permitido " – Hirnhamster

+0

Actualice su respuesta para incluir la sugerencia de @ Hirnhamster. Su guión faltante en 'UTF-8' está afectando a otras personas. – Timo

+0

@Timo: gracias por el aviso. He actualizado la respuesta ahora. –

18

Esto debería ser útil, que se encarga de casi todo el casos.

function Unaccent($string) 
{ 
    return preg_replace('~&([a-z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml|caron);~i', '$1', htmlentities($string, ENT_COMPAT, 'UTF-8')); 
} 
+1

¡Como un encanto! Gracias – Oritm

+1

@Oritm welcome. – user1518659

+1

Esto se ve increíble, pero tiene problemas con, por ejemplo, los caracteres griegos –

0

Si se habilita la extensión php Intl, puede utilizar Transliterator así:

protected function removeDiacritics($string) 
{ 
    $transliterator = \Transliterator::create('NFD; [:Nonspacing Mark:] Remove; NFC;'); 
    return $transliterator->transliterate($string); 
} 

para eliminar otros caracteres especiales (no diacríticos solamente como 'æ')

protected function removeDiacritics($string) 
{ 
    $transliterator = \Transliterator::createFromRules(
     ':: Any-Latin; :: Latin-ASCII; :: NFD; :: [:Nonspacing Mark:] Remove; :: NFC;', 
     \Transliterator::FORWARD 
    ); 
    return $transliterator->transliterate($string); 
} 
Cuestiones relacionadas