begin process at 2012 02 15 23:53:01
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Chaîne de caratère

 > FONCTION QUI GÉNÈRE UN CODE GRÂCE À L'ORTOGRAPHE ET LA PRONONCIATION D'UN MOT

FONCTION QUI GÉNÈRE UN CODE GRÂCE À L'ORTOGRAPHE ET LA PRONONCIATION D'UN MOT


 Information sur la source

Note :
Aucune note
Catégorie :Chaîne de caratère Classé sous :soundex-fr, codage string, hashcode soundex, soundex francais Niveau :Débutant Date de création :17/06/2009 Date de mise à jour :17/06/2009 17:58:25 Vu :2 628

Auteur : foofymany

Ecrire un message privé
Commentaire sur cette source (10)
Ajouter un commentaire et/ou une note

 Description

Je souhaite vous faire part d'une fonction que j'ai écrite dans le cadre de mon stage pour permettre de trier facilement des noms en fonction de leur orthographe. Grâce au code générer par cette fonction j'alimente un champs dans ma BDD et je peux faire des tris très rapide pour ainsi détecter des doublons. Cette fonction est un mélange de mon imagination et de soundexfr() implémenter en pl-sql sur(http://dgriessinger.developpez.com/postgresql/ udf/?page=chaines). Libre a vous de choisir le nombre de caractère générer par la fonction. Le couplage de my_soundex() avec le codage des n premier caractère (ici n = 4) est beaucoup plus performant que my_soundex() seule. Profiter en ! Elle est assez performante, pour info sur 15 000 champs dans ma BDD auxquels j'ai appliqué cette fonction j'ai mis 25sec.

Source

  • //------------------------------------------------------------------
  • //Génère un hashcode en fonction de l'orthographe et de la prononciation d'un nom
  • function ds_hasherNom($nom){
  • //On retire les caractères spéciaux et accentués, on met en minuscules
  • $nom = stringRemoveAccent($nom);
  • $nom = strtr($nom,"._/\<>-|(){}[]*&\"''$;?!"," ");
  • $nom=strtolower($nom);
  • //On enlève les espaces
  • $st = '';
  • for($i=0;$i<strlen($nom);$i++){
  • if($nom{$i} != ' '){
  • $st.=$nom{$i};
  • }
  • }
  • //On codes les 4 premiers caractères sur 2 chiffres chacun
  • $code = '';
  • for($i=0;$i<4;$i++){
  • $ch = $st{$i};
  • $mcar = '';
  • switch($ch){
  • case '0':$mcar.='00';break;
  • case '1':$mcar.='01';break;
  • case '2':$mcar.='02';break;
  • case '3':$mcar.='03';break;
  • case '4':$mcar.='04';break;
  • case '5':$mcar.='05';break;
  • case '6':$mcar.='06';break;
  • case '7':$mcar.='07';break;
  • case '8':$mcar.='08';break;
  • case '9':$mcar.='09';break;
  • case 'a':$mcar.='10';break;
  • case 'b':$mcar.='11';break;
  • case 'c':$mcar.='12';break;
  • case 'd':$mcar.='13';break;
  • case 'e':$mcar.='14';break;
  • case 'f':$mcar.='15';break;
  • case 'g':$mcar.='16';break;
  • case 'h':$mcar.='17';break;
  • case 'i':$mcar.='18';break;
  • case 'j':$mcar.='19';break;
  • case 'k':$mcar.='20';break;
  • case 'l':$mcar.='21';break;
  • case 'm':$mcar.='22';break;
  • case 'n':$mcar.='23';break;
  • case 'o':$mcar.='24';break;
  • case 'p':$mcar.='25';break;
  • case 'q':$mcar.='26';break;
  • case 'r':$mcar.='27';break;
  • case 's':$mcar.='28';break;
  • case 't':$mcar.='29';break;
  • case 'u':$mcar.='30';break;
  • case 'v':$mcar.='31';break;
  • case 'w':$mcar.='32';break;
  • case 'x':$mcar.='33';break;
  • case 'y':$mcar.='34';break;
  • case 'z':$mcar.='35';break;
  • }
  • $code.=$mcar;
  • }
  • //On récupère la fin du nom
  • $fin = substr($st,4);
  • $fin = strtoupper($fin);
  • //On applique la fonction soundex() sur la fin du nom
  • //Si la fin du mot existe (+ de 4 lettres)
  • if(strlen($fin)>0){
  • $code.=my_soundex($fin);
  • }else {
  • $code.='00000';
  • }
  • return $code;
  • }
  • //------------------------------------------------------------------
  • //Supprime les accents d'une chaîne
  • function stringRemoveAccent($string){
  • $result='';
  • $length=mb_strlen($string);
  • for($i=0;$i<$length;$i++)
  • switch($char=mb_substr($string,$i,1,'utf-8')){
  • case 'ä':
  • case 'à':
  • case 'â':$result.='a';break;
  • case 'é':
  • case 'è':
  • case 'ê':
  • case 'ë':$result.='e';break;
  • case 'î':
  • case 'ï':$result.='i';break;
  • case 'ô':
  • case '½':
  • case 'ö':$result.='o';break;
  • case 'ü':
  • case 'ù':
  • case 'û':$result.='u';break;
  • case 'ÿ':$result.='y';break;
  • case 'Ä':
  • case 'À':
  • case 'Â':$result.='A';break;
  • case 'ñ':$result.='n';break;
  • case 'É':
  • case 'È':
  • case 'Ê':
  • case 'Ë':$result.='E';break;
  • case 'Î':
  • case 'Ï':$result.='I';break;
  • case 'Ô':
  • case '¼':
  • case 'Ö':$result.='O';break;
  • case 'Ü':
  • case 'Ù':
  • case 'Û':$result.='U';break;
  • case 'ç':$result.='c';break;
  • case 'Ç':$result.='C';break;
  • case '¾':$result.='Y';break;
  • case 'æ':$result.='a';break;
  • case 'Æ':$result.='a';break;
  • default:$result.=$char;
  • }
  • return $result;
  • }
  • //------------------------------------------------------------------
  • //Fonction qui attribut un code de 5 caractères à une consonance phonétique
  • function my_soundex($str){
  • $st='';
  • //Recherche de la 1ere consomne
  • for($i=0;$i<strlen($str);$i++){
  • $ch = substr($str,$i,1);
  • if($ch != 'A' && $ch != 'E' && $ch != 'I' && $ch != 'O' && $ch != 'U' && $ch != 'Y' && $ch != 'H' && $ch != 'W'){
  • $st.= $ch;
  • }
  • }
  • $st2 = substr($st,0,1);
  • //Codage des consonnes suivantes
  • for($i=1;$i<strlen($st);$i++){
  • $ch = substr($st,$i,1);
  • switch($ch){
  • case 'B':
  • case 'P':$st2.='1';break;
  • case 'C':
  • case 'K':
  • case 'Q':$st2.='2';break;
  • case 'D':
  • case 'T':$st2.='3';break;
  • case 'L':$st2.='4';break;
  • case 'M':
  • case 'N':$st2.='5';break;
  • case 'R':$st2.='6';break;
  • case 'G':
  • case 'J':$st2.='7';break;
  • case 'S':
  • case 'X':
  • case 'Z':$st2.='8';break;
  • case 'F':
  • case 'V':$st2.='9';break;
  • }
  • }
  • //Si le code est moins long que 5 caractère on comble par des 0
  • if(strlen($st2)<5){
  • $st2=str_pad($st2,5,'0');
  • }
  • //Sinon on garde seulement les 5 premiers caractères
  • elseif(strlen($st2)>5){
  • $st2 = substr($st2,0,5);
  • }
  • return $st2;
  • }
//------------------------------------------------------------------
//Génère un hashcode en fonction de l'orthographe et de la prononciation d'un nom
function ds_hasherNom($nom){
	
	//On retire les caractères spéciaux et accentués, on met en minuscules
	$nom = stringRemoveAccent($nom);
	$nom = strtr($nom,"._/\<>-|(){}[]*&\"''$;?!","                       ");
	$nom=strtolower($nom);
	//On enlève les espaces
	$st = '';
	for($i=0;$i<strlen($nom);$i++){
		if($nom{$i} != ' '){
			$st.=$nom{$i};	
		}
	}
	//On codes les 4 premiers caractères sur 2 chiffres chacun
	$code = '';	
	for($i=0;$i<4;$i++){
		$ch = $st{$i};
		$mcar = '';
		switch($ch){
			case '0':$mcar.='00';break;
			case '1':$mcar.='01';break;
			case '2':$mcar.='02';break;
			case '3':$mcar.='03';break;
			case '4':$mcar.='04';break;
			case '5':$mcar.='05';break;
			case '6':$mcar.='06';break;
			case '7':$mcar.='07';break;
			case '8':$mcar.='08';break;
			case '9':$mcar.='09';break;
			case 'a':$mcar.='10';break;
			case 'b':$mcar.='11';break;
			case 'c':$mcar.='12';break;
			case 'd':$mcar.='13';break;
			case 'e':$mcar.='14';break;
			case 'f':$mcar.='15';break;
			case 'g':$mcar.='16';break;
			case 'h':$mcar.='17';break;
			case 'i':$mcar.='18';break;
			case 'j':$mcar.='19';break;
			case 'k':$mcar.='20';break;
			case 'l':$mcar.='21';break;
			case 'm':$mcar.='22';break;
			case 'n':$mcar.='23';break;
			case 'o':$mcar.='24';break;
			case 'p':$mcar.='25';break;
			case 'q':$mcar.='26';break;
			case 'r':$mcar.='27';break;
			case 's':$mcar.='28';break;
			case 't':$mcar.='29';break;
			case 'u':$mcar.='30';break;
			case 'v':$mcar.='31';break;
			case 'w':$mcar.='32';break;
			case 'x':$mcar.='33';break;
			case 'y':$mcar.='34';break;
			case 'z':$mcar.='35';break;
		}
		$code.=$mcar;
	}	
	//On récupère la fin du nom
	$fin = substr($st,4);
	$fin = strtoupper($fin);		
	//On applique la fonction soundex() sur la fin du nom
	//Si la fin du mot existe (+ de 4 lettres)
	if(strlen($fin)>0){
		$code.=my_soundex($fin);
	}else {
		$code.='00000';
	}
	return $code;
}

//------------------------------------------------------------------
//Supprime les accents d'une chaîne
function stringRemoveAccent($string){
	$result='';
	$length=mb_strlen($string);
	for($i=0;$i<$length;$i++)
		switch($char=mb_substr($string,$i,1,'utf-8')){
			case 'ä':
			case 'à':
			case 'â':$result.='a';break;
			case 'é':
			case 'è':
			case 'ê':
			case 'ë':$result.='e';break;
			case 'î':
			case 'ï':$result.='i';break;
			case 'ô':
			case '½':
			case 'ö':$result.='o';break;
			case 'ü':
			case 'ù':
			case 'û':$result.='u';break;
			case 'ÿ':$result.='y';break;
			case 'Ä':
			case 'À':
			case 'Â':$result.='A';break;
			case 'ñ':$result.='n';break;
			case 'É':
			case 'È':
			case 'Ê':
			case 'Ë':$result.='E';break;
			case 'Î':
			case 'Ï':$result.='I';break;
			case 'Ô':
			case '¼':
			case 'Ö':$result.='O';break;
			case 'Ü':
			case 'Ù':
			case 'Û':$result.='U';break;
			case 'ç':$result.='c';break;
			case 'Ç':$result.='C';break;
			case '¾':$result.='Y';break;
			case 'æ':$result.='a';break;
			case 'Æ':$result.='a';break;
			default:$result.=$char;
		} 
	return $result;
}

//------------------------------------------------------------------
//Fonction qui attribut un code de 5 caractères à une consonance phonétique
function my_soundex($str){
	$st='';
	//Recherche de la 1ere consomne
	for($i=0;$i<strlen($str);$i++){
		$ch = substr($str,$i,1);
		if($ch != 'A' && $ch != 'E' && $ch != 'I' && $ch != 'O' && $ch != 'U' && $ch != 'Y' && $ch != 'H' && $ch != 'W'){
			$st.= $ch;
		}
	}
	$st2 = substr($st,0,1);
	
	//Codage des consonnes suivantes
	for($i=1;$i<strlen($st);$i++){
		$ch = substr($st,$i,1);
		switch($ch){
			case 'B':
			case 'P':$st2.='1';break;
			case 'C':
			case 'K':
			case 'Q':$st2.='2';break;
			case 'D':
			case 'T':$st2.='3';break;
			case 'L':$st2.='4';break;
			case 'M':
			case 'N':$st2.='5';break;
			case 'R':$st2.='6';break;
			case 'G':
			case 'J':$st2.='7';break;
			case 'S':
			case 'X':
			case 'Z':$st2.='8';break;
			case 'F':
			case 'V':$st2.='9';break;
		}
	}
	
	//Si le code est moins long que 5 caractère on comble par des 0	
	if(strlen($st2)<5){
		$st2=str_pad($st2,5,'0');
	}
	//Sinon on garde seulement les 5 premiers caractères
	elseif(strlen($st2)>5){
		$st2 = substr($st2,0,5);
	}
	return $st2;
}

 Conclusion

Vos impressions, vos remarques?


 Historique

17 juin 2009 17:58:25 :
faute d'orthographe dans le titre

 Sources de la même categorie

ADRESSE ABSOLUE DE LA PAGE EN COURS, AVEC VARIABLES $_GET par Dariumis
Source avec Zip CLASSE D'OBJET DE RECHERCHE DE MOTS DANS DES TABLEAUX ET/OU ... par 8Tnerolf8
RÉCUPÉRER LES MINIATURES D'UNE VIDÉO YOUTUBE par tefa24600
Source avec Zip Source avec une capture CONVERTISSEUR DE NOMBRES EN TEXTE par macruz
Source avec Zip Source avec une capture CODAGE TEXTE >HTML, ISO, SPECIALCHARS, URL ET DECODAGE par Salva9473

Commentaires et avis

Commentaire de jeca le 18/06/2009 13:10:33

Bonjour,

Pourquoi des "switch... case..." ?
Ceci est beaucoup plus rapide, et moins de code :

  function stringRemoveAccent($string)
  {
    $remplacer = array('ä','à','â','é','è','ê','ë','î','ï','ô','½','ö','ü','ù','û','ÿ','Ä','À','Â','ñ','É','È','Ê','Ë','Î','Ï','Ô','¼','Ö','Ü','Ù','Û','ç','Ç','¾','æ','Æ');
    $par =       array('a','a','a','e','e','e','e','i','i','o','o','o','u','u','u','y','A','A','A','n','E','E','E','E','I','I','O','O','O','U','U','U','c','C','Y','a','a');

    return str_replace($remplacer, $par, $string);
  }

Sur 10 000 itérations pour une cheîne de 10 caractères, ta fonction prend 28 à 29 secondes, le code ci-dessus 11 à 12 secondes.

Ce doit être applicable aux autres fonctions.

Commentaire de kankrelune le 18/06/2009 14:09:19

La chaine remplacée étant aussi longue que la chaine de remplacement autant utiliser strtr()

------

for($i=0;$i<strlen($str);$i++){

pas bon ça... tu perd du temps et des ressources serveur...

for($i=0,$len=strlen($str);$i<$len;$i++){

------

tu as un strlen redondant en fin de code... strlen($st2)

@ tchaOo°

@ tchaOo°

Commentaire de jeca le 18/06/2009 14:20:53

"strtr()" est effectivement beaucoup plus rapide. Je ne l'avais jamais utilisée. Le code ci-dessus passe à 4 secondes.

Commentaire de foofymany le 18/06/2009 14:33:23

strtr() seul ne prend pas en compte l'encodage utf-8 càd le multi-octet. C'est pour cela que j'utilise mb_substr() puis le switch case. Je ne suis pas fou, j'ai d'abord eu l'erreur. Maintenant grâce à ça les caractère accentuée ne pas à la trappe. Après si vous n'êtes pas sur de l'utf-8 strtr() suffit!

Commentaire de exar le 19/06/2009 06:32:47

Grâce à l'ortographe ???  Est sa fonctione qu'on veut n'a bleu mens ?

Commentaire de foofymany le 22/06/2009 11:20:30

Bien sur que ça fonctionne très bien. Même mieux que soundex seul. Car cette fonction à tendance à ne prendre que les consonnes. La vous avez un mix des 2 qui rend le truc assez complet et donne des résultats très cohérents.

Commentaire de originalcompo le 22/06/2009 14:34:12

Juste une remarque: les 36 premières lignes du "switch($ch){case '0':$mcar.='00';break; ..."
peuvent être remplacé par:

  if (($ch>='0') && ($ch<='9'))
    $mcar .= '0'.$ch;
  elseif (($ch>='a') && ($ch<='z'))
    $mcar .= ord($ch)-87;

Cordialement

Commentaire de originalcompo le 22/06/2009 14:35:18

remplacéES (pardon pour l'orthographe)

Commentaire de exar le 22/06/2009 20:42:09

ORIGINALCOMPO: c'est justement à cause du titre que j'avais écris le message ci-dessus...  Il y est question d'"ortographe"...
Bien d'avoir corrigé ta faute, il y en a souvent de trop, ici, hélas.  Heureusement, parfois, la qualité du code compense la pauvreté de l'orthographe utilisée.
Enfin, dans ce cas-ci, je suppose qu'il s'agit d'une faute de frappe non relue, donc pas vue.  Dans le résumé, il n'y en a pas de trop.
FOOFYMANY: je n'ai pas testé, mais comme tu évoques le PL/SQL, je te conseille de te documenter sur le regexp_like.  Très puissant.
Cela n'enlève rien à l'utilité de ton code, pour quelqu'un qui n'a pas besoin de quelque chose d'aussi poussé que cela.
Bonne continuation !

Commentaire de kankrelune le 22/06/2009 23:35:26

Slt Foofymany... tout à fait d'accord mon commentaire sur le strtr() concerne le str_replace... si tu travaille sur du muli-byte il va de soit qu'il faut passer par l'extension mb_string... .. .

Par contre je persiste pour le strlen() dans la condition de tes for... tant que la chaine testée n'est pas remaniée dans la boucle même, ce qui est le cas ici, il ne faut surtout pas mettre ton strlen() dans la partie conditionnelle de ta boucle for... imagine tu fais 10000 itération ça te fait 9999 strlen() pour rien... c'est un détail mais qui a son importance... .. .

Au passage $st{$i} est déprécié et n'existera bientôt plus => $st[$i]

Pour le reste rien a redire ne l'ayant pas testé... .. .

@ tchaOo°

 Ajouter un commentaire




Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,328 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales