Soundex 2 francais

Soyez le premier à donner votre avis sur cette source.

Vue 20 524 fois - Téléchargée 929 fois

Description

Bon ben ceci est une première version de soundex2, un soundex francisé.
Il est basé sur un algo décrit ici : http://sqlpro.developpez.com/cours/soundex/ par Frédéric BROUARD.

Il n'est pas encore parfait (j'ai dû manquer 2-3 choses), mais il tourne déjà pas mal.
Il faudra aussi l'optimiser car il risque d'être gourmand, à la longue...!

Soundex est une méthode utilisé pour comparer phonétiquement 2 chaînes. Il existe en natif dans PHP les fonction soundex, ou metaphone, mais elles sont anglicisées.

Cette version-ci est francisé, donc prend en compte les spécificités de la langue française.

PRECISIONS SUR L'UTILITE :
Ces algo, soundex, soundex2, phonex, metaphone, assigne un code à une chaîne donnée. Ce code est calculé en fonction de la phonétique, donc de la prononciation de cette chaîne.
En l'occurence, les 2 algo présents par défaut dans php, soundex () et metaphone () ne prennent en compte que la prononciation anglaise.
celui-ci, basé sur soundex2 (un algo plus performant que soundex), est francisé, donc prend en compte la prononciation française.

Evidemment, 2 chaînes différentes peuvent avoir le même code. Par exemple, ici, 'gros' aura le même code soundex2 que 'grau'.
Ce qui veut dire, dans le cadre d'une recherche sur une base de données contenant des noms, par exemple, on peut effecyuer une recherche phonétique aussi! Bref, le mec a parlé avec un cilent par téléphone, mais il ne s'est pas comment s'écrit exactement son nom de famille...gros, graus, grau, graux, greaux...? etc... Il tapoe par exemple gros, et effectue une recherche soundex. Cette recherche lui ressortira tous les noms dont le code soundex est le même que 'gros'. Donc si le client s'appelait 'Graux', il le trouvera.

Couplé à l'algo de levenshtein (fonction interne php) en plus, on peut avoir une recherche phonétique par pertinence...les codes identiques en premiers, puis ceux un peu différents, etc...jusqu'à un degré de différence voulu.

Le mieux, dans le cadre d'une bdd, est évidemment de stocker le code soundex2 dans la base, histoire de ne pas le recalculer à chaque recherche (pour info, sur ma bécane, 10000 tours de boucle sur le tableau que j'ai mis en exemple dans index.php, donc 10000 * 11 chaînes dont on doit calculer le code soundex2, ça me prend une 20aine de secondes. Et encore, je n'ai pas optimisé l'algo).

Source / Exemple :


<?php
/**


*

  • author Johan Barbier <barbier_johan@hotmail.com>
  • /
class soundex2 { /**
  • public sString
  • main string we work on
  • /
public $sString = ''; /**
  • vowels replacement array
  • /
private $aReplaceVoy1 = array ( 'E' => 'A', 'I' => 'A', 'O' => 'A', 'U' => 'A' ); /**
  • consonnants replacement array
  • /
private $aReplaceGrp1 = array ( 'GUI' => 'KI', 'GUE' => 'KE', 'GA' => 'KA', 'GO' => 'KO', 'GU' => 'K', 'CA' => 'KA', 'CO' => 'KO', 'CU' => 'KU', 'Q' => 'K', 'CC' => 'K', 'CK' => 'K' ); /**
  • other replacement array
  • /
private $aReplaceGrp2 = array ( 'ASA' => 'AZA', 'KN' => 'NN', 'PF' => 'FF', 'PH' => 'FF', 'SCH' => 'SSS' ); /**
  • endings replacement array
  • /
private $aEnd = array ( 'A', 'T', 'D', 'S' ); /**
  • public function build
  • core function of the class, go through the whole process
  • @Param string sString : the string we want to check
  • /
public function build ($sString) { /**
  • let's check it's a real string...
  • /
if (is_string ($sString)) { $this -> sString = $sString; } /**
  • remove starting and ending spaces
  • /
$this -> sString = trim ($this -> sString); /**
  • remove special french characters
  • /
$this -> trimAccent (); /**
  • string to upper case
  • /
$this -> sString = strtoupper ($this -> sString ); /**
  • let's remove every space in the string
  • /
$this -> sString = str_replace (' ', '', $this -> sString); /**
  • let's remove every '-' in the string
  • /
$this -> sString = str_replace ('-', '', $this -> sString); /**
  • let's process through the first replacement array
  • /
$this -> arrReplace ($this -> aReplaceGrp1); /**
  • let's process through th vowels replacement
  • /
$sChar = substr ($this -> sString, 0, 1); $this -> sString = substr ($this -> sString, 1, strlen ($this -> sString) - 1); $this -> arrReplace ($this -> aReplaceVoy1); $this -> sString = $sChar.$this -> sString; /**
  • let's process through the second replacement array
  • /
$this -> arrReplace ($this -> aReplaceGrp2, true); /**
  • let's remove every 'H' but those prededed by a 'C' or an 'S'
  • /
$this -> sString = preg_replace ('/(?<![CS])H/', '', $this -> sString); /**
  • let's remove every 'Y' but those preceded by an 'A'
  • /
$this -> sString = preg_replace ('/(?<!A)Y/', '', $this -> sString); /**
  • remove endings in aEnd
  • /
$length = strlen ($this -> sString) - 1; if (in_array ($this -> sString{$length}, $this -> aEnd)) { $this -> sString = substr ($this -> sString, 0, $length); } /**
  • let's remove every 'A', but the one at the beginning of the string, if any.
  • /
$sChar = ''; if ($this -> sString{0} === 'A') { $sChar = 'A'; } $this -> sString = str_replace ('A', '', $this -> sString); $this -> sString = $sChar.$this -> sString; /**
  • let's have only 1 occurence of each letter
  • /
$this -> sString = preg_replace( '`(.)\1`', '$1', $this -> sString ); /**
  • let's have the final code : a 4 letters string
  • /
$this -> getFinal (); } /**
  • private function getFinal
  • gets the first 4 letters, pads the string with white space if the string length < 4
  • /
private function getFinal () { if (strlen ($this -> sString) < 4) { $this -> sString = str_pad ($this -> sString, 4, ' ', STR_PAD_RIGHT); } else { $this -> sString = substr ($this -> sString, 0, 4); } } /**
  • private function trimAccent
  • remove every special French letters
  • /
private function trimAccent () { $this -> sString = htmlentities(strtolower($this -> sString )); $this -> sString = preg_replace("/&(.)(acute|cedil|circ|ring|tilde|uml|grave);/", "$1", $this -> sString ); $this -> sString = preg_replace("/([^a-z0-9]+)/", "-", html_entity_decode($this -> sString )); $this -> sString = trim($this -> sString , "-"); } /**
  • private function arrReplace
  • replacement method, given an array
  • @Param array tab : the replacement array to be used
  • @Param bool pref : if false, just replace keys by values; if true, do the same but only with prefix
  • /
private function arrReplace (array $tab, $pref = false) { $fromRep = array_keys ($tab); $toRep = array_values ($tab); if (false === $pref) { $this -> sString = str_replace ($fromRep, $toRep, $this -> sString); } else { foreach ($fromRep as $clef => $val) { $length = strlen ($val); if (substr ($this -> sString, 0, $length) === $val) { $this -> sString = substr_replace ($this -> sString, $toRep[$clef], 0, $length); } } } } } ?>

Codes Sources

A voir également

Ajouter un commentaire Commentaires
Messages postés
2268
Date d'inscription
mercredi 27 novembre 2002
Statut
Membre
Dernière intervention
13 septembre 2013
3
Encore une question... Il prend en compte les espaces? Mon but c'est de bosser sur des noms de métiers.
Les métiers "infirmier" "infirmier reponsable" me renvoie les deux "INFR". C'est normal?

Merci!

Raf
Messages postés
2268
Date d'inscription
mercredi 27 novembre 2002
Statut
Membre
Dernière intervention
13 septembre 2013
3
Salut! :-)
Sais-tu comment a tendance à évoluer la longueur des chaînes que tu passes là dedans? Je suppose que ca raccourci mais je préfère être sûr.

Merci!

Raf
Messages postés
6
Date d'inscription
mercredi 7 juin 2006
Statut
Membre
Dernière intervention
22 juin 2007

Salut,

J'ai une erreur à l'execution :

Parse error: parse error, expecting `T_OLD_FUNCTION' or `T_FUNCTION' or `T_VAR' or `'}'' in ***\soundex\class\php5\soundex2.cls.php on line 15

Comprend pas ... :(
Messages postés
10840
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
22
Hello,

ah, des oublis; en fait, j'ai fait la version php4 à l'aveugle, je n'ai pas eu l'occasion de la tester sur un serveur interprétant php4.
ceci dit, array est un oubli impardonnable, c'était voyant...array_combine, j'étais persuadé qu'il existait en php4, mea culpa à fond.
Messages postés
147
Date d'inscription
lundi 16 août 2004
Statut
Membre
Dernière intervention
14 novembre 2009

Quelques menues broutilles à signaler, concernant la version "php4" de ton appli :

- dans "soundex2.cls.php", php4 ne semble pas apprécier la présence du mot-clé "array" à la ligne 177 :
function arrReplace (array $tab, $pref = false) {

- dans "index.php", la fonction "array_combine()" n'étant pas reconnue par php4, il faut l'écrire :

function array_combine($key,$value)
{
$m=count($key);
$n=count($value);

if ($m!=$n || !$n) return false;

for ($i=0;$i<$m;$i++) $rslt[$key[$i]]=$value[$i];
return $rslt;
}

Pour ce code, je n'ai fait qu'appliquer à la lettre les explications données dans l'aide de PHP.
Amicalement.
Afficher les 13 commentaires

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.