2009-11-20 8 views
14

Je fais un site suédois, et les lettres suédoises sont å, ä, et ö.Comment supprimer diacritics du texte?

Je dois créer une chaîne entrée par un utilisateur pour qu'il devienne sécurisé avec PHP.

Fondamentalement, besoin de convertir tous les caractères pour souligner, tous sauf ceux-ci:

A-Z, a-z, 1-9 

et tous les suédois devraient être convertis comme ceci:

« A » à « a » et « a » à 'a' et 'ö' à 'o' (il suffit de retirer les points ci-dessus).

Le reste devrait devenir underscore comme je l'ai dit. Je ne suis pas bon à des expressions régulières, donc j'apprécierais l'aide les gars!

Merci

REMARQUE: PAS UrlEncode ... Je dois stocker dans une base de données ... etc etc, urlencode ne fonctionnera pas pour moi.

Répondre

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

Veuillez noter que 'normalizer_normalize()' fait partie de l'extension PHP _intl_ qui n'est pas toujours active. Cette extension a été ajoutée au noyau dans PHP 5.3, mais dans la plupart des distributions Linux, elle n'est pas active par défaut. Par exemple, dans Debian, il se trouve dans le paquet séparé _php5-intl_. Si vous ne pouvez pas l'installer/l'activer, essayez _ext/iconv_. à la place –

+1

@Mytskine J'ai ajouté le commentaire. Merci de l'avoir signalé: c'était mon défaut pour moi, donc je n'y ai pas réfléchi. –

4

Si vous êtes simplement intéressé par la sécurité des URL, alors vous voulez urlencode.

Renvoie une chaîne dans laquelle tous les caractères non alphanumériques, à l'exception de -_. ont été remplacés par un signe de pourcentage (%) suivi de deux chiffres hexadécimaux et de espaces codés comme des signes plus (+). Il est codé de la même manière que les données affichées d'un formulaire WWW sont codées , de la même manière que dans application/x-www-form-urlencoded type de média. Ceci diffère de l'encodage » RFC 1738 (voir rawurlencode()) en ce que pour des raisons historiques, les espaces sont codés comme des signes plus (+).

Si vous voulez vraiment dépouiller tous les non AZ, az, 1-9 (? Quel est le problème avec 0, en passant), alors vous voulez:

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

désolé, oublié de mentionner que je n'ai pas besoin d'urlencode –

+1

Si vous voulez le rendre sûr, alors vous voulez urlencode. Le fait que vous voulez le stocker dans une base de données est à côté du point (à part que vous voulez l'échapper pour votre requête d'insertion SQL en plus de rendre l'url sécuritaire). – Quentin

+0

Vous ne comprenez pas. Il veut qu'il soit sûr d'utiliser comme URL, mais pas si sûr. Il préférerait qu'il échoue sur un espace ou une esperluette. – JohnFx

7

et tous les suédois devraient être converti comme ceci:

'å' à 'a' et 'ä' à 'a' et 'ö' à 'o' (il suffit de retirer les points ci-dessus).

Utilisez normalizer_normalize() pour vous débarrasser de diacritical marks.

Le reste devrait devenir des traits de soulignement, comme je l'ai dit.

Utilisation preg_replace() avec un motif de [\W] (i.o.w: un caractère qui ne correspond pas à des lettres, des chiffres ou underscore) pour les remplacer par des underscores.

résultat final devrait ressembler à:

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

Une solution simple consiste à utiliser la fonction str_replace avec recherche et remplacement des tableaux de lettres.

0

Vous n'avez pas besoin de fantaisie regexps pour filtrer les caractères suédois, il suffit d'utiliser le strtr function pour "traduire" eux, comme:

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

-> Sortie: www.maao.com :)

+1

Ce n'est qu'un cauchemar de maintenance pour couvrir des milliers de ces personnages connus dans le monde humain. – BalusC

2

aussi simple que

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

vous utilisez en supposant le même encodage pour vos données et votre code.

+1

'/ [^ a-z0-9] +/i' ou '/ [^ A-Za-z0-9] + /' pour ignorer le cas –

+0

strtr est plus pratique pour "traduire" des ensembles de caractères, comme: $ str = strtr ($ str, "aëïöü", "aeiou"); il n'utilise pas de tableaux – danii

+2

Les tableaux sont cumbercome pour maintenir un petit millier de caractères avec des signes diacritiques connus dans le monde humain. Utilisez simplement 'normalizer'. – BalusC

18

Utilisez iconv pour convertir des chaînes à partir d'un encodage donné à ASCII, puis remplacer les caractères non alphanumériques à l'aide 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; 

Résultat:

raksmorgas_och_kottbullar 
+1

Vous devriez utiliser "UTF-8" comme ceci: '$ data = iconv ('UTF-8', 'ASCII // TRANSLIT', $ data);' - sinon vous pourriez rencontrer cette notice: "Mauvais jeu de caractères, conversion de "UTF8" à "ASCII // TRANSLIT" n'est pas autorisé " – Hirnhamster

+0

Veuillez mettre à jour votre réponse pour inclure la suggestion de @ Hirnhamster. Votre trait d'union manquant dans 'UTF-8' affecte d'autres personnes. – Timo

+0

@Timo: Merci pour l'avis - J'ai mis à jour la réponse maintenant. –

18

Cela devrait être utile qui gère presque tous les cas.

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

Comme un charme! Merci – Oritm

+1

@Oritm bienvenue. – user1518659

+1

Cela semble incroyable, mais a des problèmes avec des caractères grecs par exemple –

0

Si l'extension intl php est activée, vous pouvez utiliser Transliterator comme ceci:

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

Pour supprimer d'autres caractères spéciaux (non diacritiques seulement comme 'æ')

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