Page 1 sur 1

Sans Accent et UTF-8

Posté : 06 déc. 2008, 19:10
par Elie
Bonjour,

J'utilise ma super fonction pour simplifier des urls qui est la suivante :
	// Simplification d'une chaine
	function simplification($chaineNonValide) {
	
	  $chaineValide = strtolower(strtr($chaineNonValide, "ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ", "aaaaaaaaaaaaooooooooooooeeeeeeeecciiiiiiiiuuuuuuuuynn"));
 	  $search = array ('@[ ]@i','@[^a-zA-Z0-9_-]@');
	  $replace = array ('_','');
	 
	  return trim(strtolower(preg_replace($search, $replace, $chaineValide)), '_');
		
	}
Cela marche très bien si mon fichier est en charset "Europe occidentale" mais le format UTF-8 se banalisant, et surtout dans dreamweaver, je n'ai trouvé que cette solution pour que ma fonction marche :
	// Simplification d'une chaine
	function simplification($chaineNonValide) {
	
	  $chaineValide = strtr(utf8_decode($chaineNonValide), @iconv("UTF-8", "ISO-8859-1", "ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ"), "aaaaaaaaaaaaooooooooooooeeeeeeeecciiiiiiiiuuuuuuuuynn");
	  $search = array ('@[ ]@i','@[^a-zA-Z0-9_-]@');
	  $replace = array ('_','');
	 
	  return trim(strtolower(preg_replace($search, $replace, $chaineValide)), '_');
				
	}
Malheureusement la fonction iconv n'est pas pris en compte dans tous les hebergeurs.

Avez-vous une autre méthode identique pour simplifier une chaine ?

Merci, Elie

Posté : 06 déc. 2008, 20:26
par Hywan
Hey :),

C'est une excellente question …
Il faudrait réussir à faire un système générique pour toutes les langues, mais ce n'est pas gagné hmm. À mon avis, tu ne peux qu'avec un dictionnaire de correspondances. Il faut que tes sources soient en UTF-8 aussi (sinon ça ne risque pas de marcher).

Une chose aussi, dans ce genre de système on ne considère que les accents, mais il y a aussi les ligatures : œ (oe), æ (ae), fi (fi) etc., et les caractères du genre … (différent de ...). L'utilisateur peut également écrire ß etc. (bon on considère qu'on change d'alphabet ici). Tous ces caractères que je t'ai donné sont accessibles sur mon clavier avec seulement deux touches (Alt + : o, a, g, ;, b etc.). Il ne faut pas non plus oublier les tirets moyens et longs. Je ne sais pas si le moyen est accessible à mon clavier, mais le long est — (la taille de deux courts, soit deux traits d'unions).
Pareil aussi si l'utilisateur entre € ou £, et j'en passe !
On peut dire qu'on supprime les ponctuations et les symboles, mais pour les ligatures, ça change pas mal de choses :?.

Édition : pour ß, on l'utilise en allemand, donc avec le même alphabet (à ß près) que nous. Et je pareille pour l'espagnol où on trouve un double « f » ligaturé.

Posté : 06 déc. 2008, 21:00
par AB
strtr() n'est pas adapté à la manipulation de chaines utf8.
Utilise str_replace à la place.

Posté : 06 déc. 2008, 21:56
par Elie
2 bonnes réponses interessantes :)

Il faudrait effectivement que je complete mes caractères.
Et sinon effectivement avec str_replace ca marche mais la fonction est vraiment moins belle ...
2 Gros array() à la con :
	// Simplification d'une chaine
	function simplification($chaineNonValide) {
	
	  $chaineValide = str_replace(
						  array('À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'à', 'á', 'â', 'ã', 'ä', 'å', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', 'Ø', 'ò', 'ó', 'ô', 'õ', 'ö', 'ø', 'È', 'É', 'Ê', 'Ë', 'è', 'é', 'ê', 'ë', 'Ç', 'ç', 'Ì', 'Í', 'Î', 'Ï', 'ì', 'í', 'î', 'ï', 'Ù', 'Ú', 'Û', 'Ü', 'ù', 'ú', 'û', 'ü', 'ÿ', 'Ñ', 'ñ'),
						  array('a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'c', 'c', 'i', 'i', 'i', 'i', 'i', 'i', 'i', 'i', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'y', 'n', 'n'),
						  $chaineNonValide
						);
	  $search = array ('@[ ]@i','@[^a-zA-Z0-9_-]@');
	  $replace = array ('_','');

	  return trim(strtolower(preg_replace($search, $replace, $chaineValide)), '_');
				
	}
J'en profite pour poser une autre question car j'ai remarqué ca en faisant mes tests :
	echo 'La longeur de À retourne '.strlen('À'); // La longeur de À retourne 2

Posté : 06 déc. 2008, 23:13
par Hywan
Pour ton premier problème de tableau (que c'est trop long), regarde du côté de str_split().

Et indice : À = `A, donc bien deux caractères :) mais après, ça dépend de l'encodage.

Posté : 07 déc. 2008, 00:00
par Elie
Tu aurais du parler de l'indice de À = `A avant de parler de str_split :)
echo count(str_split('ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ', 1)); // return 106
Je me contenterai de ma version longue qui marche :) Meme si je ne m'avoue pas vaincu et que je sais que l'on va trouver une version plus simple que l'on pourra proposer dans php6 !

Posté : 07 déc. 2008, 05:40
par AB
Et sinon effectivement avec str_replace ca marche mais la fonction est vraiment moins belle ...
Ben si quand on te donne une solution tu t'arrêtes à la beauté du code, somme toute très relative en programmation, faut changer de métier :lol:

Sinon pour le reste tu as mis le doigt sur le pb : strlen() comme pas mal d'autres fonctions php se basent sur le nombre d'octets retournés. Et les caractères accentués en utf8 sont codés sur deux octets - contre un seul pour les caractères non accentués - ce qui est à l'origine de ces problèmes comme je le souligne dans la note à la fin de la première partie de ce tuto http://www.phpfrance.com/forums/voir_sujet-242539.php
Pour strlen, il existe une solution (cf le tuto indiqué ci dessus) mais pour d'autres fonctions comme strtr() il est préférable de ne pas l'utiliser puis qu'on ne peux pas mentionner le charset à utiliser.

Posté : 07 déc. 2008, 11:38
par Hywan
Sinon tu peux tout simplement regarder ces fonctions : http://php.net/mbstring.
Ce serait en attendant PHP 5.3 :).

Posté : 07 déc. 2008, 11:50
par Hywan
Il y a aussi cet article de vendredi sur PHPro : Decode UTF-8, ça devrait t'être utile :).

Posté : 07 déc. 2008, 14:10
par Invité
Il y a aussi cet article de vendredi sur PHPro : Decode UTF-8, ça devrait t'être utile :).
Effectivement, ca m'est plus qu'utile ... :)

Posté : 07 déc. 2008, 22:25
par AB
J'ai regardé ce tableau de correspondance.

Y'a quelque chose que je trouve bizarre : ß est remplacé par Y :?:

En copiant collant ce caractère ß dans google on trouve une toute autre correspondance :-k

Posté : 08 déc. 2008, 00:44
par jojolapine
C'est deux "s" la correspondance!!
A nostalgie quand tu nous prends...
Les cours d'allemand du collège qui remontent... :)

Posté : 08 déc. 2008, 01:06
par Hywan
C'est deux "s" la correspondance!!
Ça dépend de la région où tu es en Allemagne :).

Si tu t'intéresses à Unicode, tu verras que c'est un casse-tête incroyable mais tellement passionnant qu'on y passe volontiers des mois à l'étudier.

Posté : 08 déc. 2008, 01:38
par AB
Oui peut-être mais d'après ce que j'ai lu la correspondance 'ss' pour 'ß' semble bien plus appropriée que 'Y', non ?