OVH Cloud OVH Cloud

Recherche approximative

5 réponses
Avatar
Cleo
Bonjour,

Je recherche des techniques permettant la comparaison floue de deux chaînes
de caractères en php. J'ai bien sûr testé soundex et metaphone mais les
résultats sont déplorables car ils simplifient les chaînes en se basant sur
des equivalences de prononciation anglosaxones. De plus il semble difficile
(aux vues de l'algorithme soundex) de faire de la recherche par sous-chaîne
(contains ou like).

Existe-t'il dans l'univers open-source php des convertisseurs Graphème ->
Phonème ?
Ou bien, avez-vous d'autres solutions à me soumettre ?

--
Cléo.

--

5 réponses

Avatar
Kawai
Bonjour

il faut regarder du coté de l'algo de Levenshtein qui calcule la
distance entre 2 chaines ..

http://fr2.php.net/manual/fr/function.levenshtein.php

Kawai ^_^


Bonjour,

Je recherche des techniques permettant la comparaison floue de deux chaînes
de caractères en php. J'ai bien sûr testé soundex et metaphone mais les
résultats sont déplorables car ils simplifient les chaînes en se basant sur
des equivalences de prononciation anglosaxones. De plus il semble difficile
(aux vues de l'algorithme soundex) de faire de la recherche par sous-chaîne
(contains ou like).

Existe-t'il dans l'univers open-source php des convertisseurs Graphème ->
Phonème ?
Ou bien, avez-vous d'autres solutions à me soumettre ?



--

Avatar
P'tit Marcel
Cleo wrote:

Je recherche des techniques permettant la comparaison floue de deux
chaînes de caractères en php. J'ai bien sûr testé soundex et metaphone
mais les résultats sont déplorables car ils simplifient les chaînes en
se basant sur des equivalences de prononciation anglosaxones.


On a déjà parlé sur ce forum de la "francisation" de l'algorithme de
soundex, par exemple

Message-ID: de moi-même :-)
Message-ID: <3f622c05$0$13301$

en gros c'est assez facile d'adapter soundex à la prononciation
française, soit en modifiant le source C de la fonction et en
recompilant php, soit en écrivant l'algo en php. mais comme tu le
soulignes, la comparaison se base essentiellement sur les 2 premières
lettres.


De plus il semble difficile (aux vues de l'algorithme soundex) de
faire de la recherche par sous-chaîne (contains ou like).


peut être levensheim comme suggéré par Kawai


Existe-t'il dans l'univers open-source php des convertisseurs
Graphème > -> Phonème ?


il faudrait un convertisseur propre au français. Je ne suis pas sûr de
l'efficacité d'un algorithme. Jette donc un cil sur les bases de
données, genre http://www.lexique.org


eca
--
P'tit Marcel

--

Avatar
Benoit F
comparaison floue de deux chaînes de caractères en php...
soundex et metaphone ... prononciation anglosaxones.


Bonjour

Regardez ici : http://sqlpro.developpez.com/cours/soundex/
Il y a quelques informations et algoritmes

--
Benoit F.

--

Avatar
Cleo
Merci bien pour tes infos, j'ai implémenté l'algo phonex et le bidouillant
un peu:
- j'ai modifié la règle 8 pour transformer les 'graphèmes' du type "anno" en
[->ano] et non pas en [->1no]

Voilà,
Toute critique est la bienvenue ...

--
Cléo.


------------------------ A
TESTER -------------------------------------------
function Phonex($val)
{
//Algorithme Phonex
//Copyright Frédéric BROUARD (31/3/99)
//Modifié le 18/10/04

$val = strtolower($val);

//1. remplacer les y par des i
$val = str_replace("y","i",$val);
echo "<br/>01: ".$val;

//2. supprimer les h qui ne sont pas précédés de c ou de s ou de p
$val = preg_replace("/([^csp])h/", "$1", $val);
$val = preg_replace("/^h/", "", $val);
echo "<br/>02: ".$val;

//3. remplacement du ph par f
$val = str_replace("ph","f",$val);
echo "<br/>03: ".$val;

//4. remplacer les groupes de lettres suivantes :
// gan -> kan
// gam -> kam
// gain -> kain
// gaim -> kaim
$val =
str_replace(array("gan","gam","gain","gaim"),array("kan","kam","kain","kaim"),
$val);
echo "<br/>04: ".$val;

//5. remplacer les occurrences suivantes,
// si elles sont suivies par une lettre a, e, i, o, ou u :
// ain -> yn
// ein -> yn
// aim -> yn
// eim -> yn
$val = preg_replace("/[ae]i[nm]([aeiou])/","yn$1",$val);
echo "<br/>05: ".$val;

//6. remplacement de groupes de 3 lettres (sons 'o', 'oua', 'ein') :
// eau -> o
// oua -> 2
// ein -> 4
// ain -> 4
// eim -> 4
// aim -> 4
$val = preg_replace("/[ae]i[nm]/","4",$val);
$val = str_replace("eau","o",$val);
$val = str_replace("oua","2",$val);
echo "<br/>06: ".$val;

//7. remplacement du son 'é' :
// é -> y
// è -> y
// ê -> y
// ai -> y
// ei -> y
// er -> yr
// ess -> yss
// et -> yt
$val = str_replace("ess","yss",$val);
$val = str_replace("er","yr",$val);
//$val = str_replace("et","yt",$val);
$val = str_replace("et","y",$val);
$val = str_replace(array("é","è","ê","ai","ei"),"y",$val);
echo "<br/>07: ".$val;

//8. remplacer les groupes de 2 lettres suivantes (son 'an' et 'in'),
// sauf s'il sont suivi par une lettre a, e, i o, u ou un son 1 à 4 :
// an -> 1
// am -> 1
// en -> 1
// em -> 1
// in -> 4
$val = preg_replace("/[ae]n([^naeiou1234])/","1$1",$val);
$val = preg_replace("/[ae]m([^maeiou1234])/","1$1",$val);
$val = preg_replace("/[ae][nm]$/","1",$val);
$val = preg_replace("/in([^naeiou1234])/","4$1",$val);
$val = preg_replace("/in$/","4",$val);
echo "<br/>08: ".$val;

//9. remplacer les s par des z
// s'ils sont suivi et précédés des lettres a, e, i, o,u ou d'un son 1 à 4
$val = preg_replace("/[aeiou1234]s[aeiou1234]/","z",$val);
echo "<br/>09: ".$val;

//10. remplacer les groupes de 2 lettres suivants :
// oe -> e
// eu -> e
// au -> o
// oi -> 2
// oy -> 2
// ou -> 3
$val =
str_replace(array("oe","eu","au","oi","oy","ou"),array("e","e","o","2","2","3"),$val);
echo "<br/>10: ".$val;

//11. remplacer les groupes de lettres suivants
// ch -> 5
// sch -> 5
// sh -> 5
// ss -> s
// sc -> s
$val =
str_replace(array("sch","ch","sh","ss","sc"),array("5","5","5","s","s"),$val);
echo "<br/>11: ".$val;

//12. remplacer le c par un s s'il est suivi d'un e ou d'un i
$val = preg_replace("/c([ei])/","s$1",$val);
echo "<br/>12: ".$val;

//13. remplacer les lettres ou groupe de lettres suivants :
// c -> k
// q -> k
// qu -> k
// gu -> k
// ga -> ka
// go -> ko
// gy-> ky
$val =
str_replace(array("gu","ga","go","gy","qu","q","c"),array("k","ka","ko","ky","k","k","k"),$val);
echo "<br/>13: ".$val;

//14. remplacer les lettres suivante :
// a -> o
// d -> t
// p -> t
// j -> g
// b -> f
// v -> f
// m -> n
$val =
str_replace(array("a","d","p","j","b","v","m"),array("o","t","t","g","f","f","n"),$val);
echo "<br/>14: ".$val;

//15. Supprimer les lettres dupliquées
$tmp = $val ;
$val = $tmp[0];
$i = 0;
for( $j=1; $j<strlen($tmp); ++$j) if($val[$i]!=$tmp[$j]) { $i++; $val .=
$tmp[$j]; }
unset($tmp,$i,$j);
echo "<br/>15: ".$val;

//16. Supprimer les terminaisons suivantes : t, x
$val = preg_replace("/[xt]$/","",$val);
echo "<br/>16: ".$val;

//17. Supprimer les blancs
$val = preg_replace("/s/","",$val);
echo "<br/>17: ".$val;

return $val;
}

--
Avatar
Cleo
Pour ceux qui sont intéressés, encore une modif sur la règle 8.

//8. remplacer les groupes de 2 lettres suivantes (son 'an' et 'in'),
// sauf s'il sont suivi par une lettre a, e, i o, u ou un son 1 à 4 :
// an -> 1
// am -> 1
// en -> 1
// em -> 1
// in -> 4
$val = preg_replace("/[ae]n([^naeiouy1234])/","1$1",$val);
$val = preg_replace("/[ae]m([^maeiouy1234])/","1$1",$val);
$val = preg_replace("/[ae][nm]$/","1",$val);
$val = preg_replace("/in([^naeiouy1234])/","4$1",$val);
$val = preg_replace("/in$/","4",$val);

--
Cléo.

--