web-dev-qa-db-fra.com

Comment supprimer les accents et transformer les lettres en caractères "simples" ASCII caractères?

Quelle est la façon la plus efficace de supprimer les accents d'une chaîne, par ex. ÈâuÑ devient Eaun?

Existe-t-il une manière simple et intégrée de me manquer ou une expression régulière?

44
Mark Lalor

Si vous avez installé iconv, essayez ceci (l'exemple suppose que votre chaîne d'entrée est en UTF-8):

echo iconv('UTF-8', 'ASCII//TRANSLIT', $string);

(iconv est une bibliothèque pour convertir entre toutes sortes d'encodages; elle est efficace et incluse avec de nombreuses distributions PHP par défaut. Surtout, c'est certainement plus facile et plus résistant aux erreurs que d'essayer de rouler votre propre solution (saviez-vous qu'il y a une "lettre latine N avec une boucle"? Moi non plus .))

52
Piskvor

J'ai trouvé une solution, qui fonctionnait dans tous mes cas de test (copiée de http://php.net/manual/en/transliterator.transliterate.php ):

var_dump(transliterator_transliterate('Any-Latin; Latin-ASCII; [\u0080-\u7fff] remove',
    "A æ Übérmensch på høyeste nivå! И я люблю PHP! есть. fi ¦"));
// string(50) "A ae Ubermensch pa hoyeste niva! I a lublu PHP! est. fi "

voir: http://www.php.net/normalizer

EDIT: Cette solution est indépendante du jeu de paramètres régionaux en utilisant setlocale (). Un autre avantage par rapport à iconv () est que même les caractères non latins ne sont pas ignorés.

EDIT2: J'ai découvert qu'il y a des caractères qui ne sont pas couverts par la translittération que j'ai postée à l'origine. Any-Latin traduit le caractère cyrillique ь à un caractère qui ne rentre pas dans un jeu de caractères latin: ʹ ( http://en.wikipedia.org/wiki/Prime_%28symbol%29 ). J'ai ajouté [\u0100-\u7fff] remove pour supprimer tous ces caractères non latins. J'ai également ajouté un test au texte;)

Je suggère qu'ils signifient l'alphabet latin et non l'un des jeux de caractères latins par Latin ici. Mais de toute façon - à mon avis, ils devraient le translitérer en quelque chose ASCII puis dans Latin-ASCII ...

EDIT3: Désolé pour un autre changement ici. J'ai dû réduire les caractères à u0080 au lieu de u0100, pour obtenir uniquement les caractères ASCII en sortie. Le test ci-dessus est mis à jour.

48
SimonSimCity

Republier ceci à la demande de @palantir ...

Je trouve iconv complètement peu fiable et je n'aime pas les solutions preg_replace et les grands tableaux ... donc ma façon préférée (et la seule méthode fiable que j'ai trouvée) est ...

function toASCII( $str )
{
    return strtr(utf8_decode($str), 
        utf8_decode(
        'ŠŒŽšœžŸ¥µÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿ'),
        'SOZsozYYuAAAAAAACEEEEIIIIDNOOOOOOUUUUYsaaaaaaaceeeeiiiionoooooouuuuyy');
}
20
neokio

Vous pouvez utiliser iconv pour translittérer les caractères en US-ASCII ordinaire, puis utiliser une expression régulière pour supprimer les caractères non alphabétiques:

preg_replace('/[^a-z]/i', '', iconv("UTF-8", "US-ASCII//TRANSLIT", $text))

Une autre façon serait d'utiliser le Normalizer pour normaliser le Normalization Form KD (NFKD) puis de supprimer les caractères de marque:

preg_replace('/\p{Mn}/u', '', Normalizer::normalize($text, Normalizer::FORM_KD))
13
Gumbo

Remarque: je republie cela à partir d'une autre question similaire dans l'espoir que cela soit utile aux autres.

J'ai fini par écrire une bibliothèque PHP basée sur URLify.js du projet Django, car j'ai trouvé iconv () trop incomplet. Vous pouvez le trouver ici:

https://github.com/jbroadway/urlify

Gère les caractères latins ainsi que le grec, le turc, le russe, l'ukrainien, le tchèque, le polonais et le letton.

12
Johnny Broadway