Fonction qui génère un code grâce à l'ortographe et la prononciation d'un mot

Soyez le premier à donner votre avis sur cette source.

Snippet vu 4 186 fois - Téléchargée 17 fois

Contenu du snippet

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 / Exemple :


//------------------------------------------------------------------
//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?

A voir également

Ajouter un commentaire

Commentaires

kankrelune
Messages postés
1293
Date d'inscription
mardi 9 novembre 2004
Statut
Membre
Dernière intervention
21 mai 2015

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°
cs_exar
Messages postés
286
Date d'inscription
vendredi 5 décembre 2003
Statut
Membre
Dernière intervention
22 avril 2012
1
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 !
originalcompo
Messages postés
65
Date d'inscription
dimanche 3 avril 2005
Statut
Membre
Dernière intervention
9 octobre 2007

remplacéES (pardon pour l'orthographe)
originalcompo
Messages postés
65
Date d'inscription
dimanche 3 avril 2005
Statut
Membre
Dernière intervention
9 octobre 2007

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
foofymany
Messages postés
2
Date d'inscription
mardi 8 janvier 2008
Statut
Membre
Dernière intervention
22 juin 2009

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.

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.