JeuWeb - Crée ton jeu par navigateur
recherche de mots - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : recherche de mots (/showthread.php?tid=678)



recherche de mots - gtsoul - 14-02-2007

J'implémente un système de rumeurs, et l'un des principes que je veux installer est l'interdépendance des rumeurs entre elles :
Sujet de la rumeur | description
_ Argoth : Argoth est installée dans la plaine de BrumeVent
_ BrumeVent : BrumeVent est la plaine couvrant le littoral méridionnal du royaume.

Lorsque j'affiche la rumeur d'Argoth, le mot "Brumevent" apparait, et je voudrais faire un lien hypertexte vers ce sujet pour afficher la rumeur parlant de BrumeVent.
Dans le cas de BrumeVent, je parle du "littoral méridionnal" et du royaume ; aussi je voudrais afficher les rumeurs les concernant.

Maintenant la question, j'ai une table rumeur avec les noms (Argoth, BrumeVent, royaume ...) et j'ai une rumeur "BrumeVent est la plaine couvrant le littoral méridionnal du royaume",
pour chaque mot compris dans la bdd, je veux afficher un lien
Comme ceci
"BrumeVent est la plaine couvrant le littoral méridionnal du royaume"

Je sépare les mots, grâce à l'espace et je fais une requête pour chaque mot. C'est long et coûteux, et je ne peux pas atteindre les ensembles de mots comme "littoral méridionnal". Y'a-t-il une meilleur solution ?


RE: recherche de mots - Seren - 14-02-2007

Je ne suis pas sûr de comprendre les détails.

Mais les idées que j'ai en lisant ça :
1. Stocker le lien en HTML avec la rumeur. Comme ça, la coûteuse et longue recherche est faite une seule fois à l'initialisation quand tu écris ta rumeur.
Par exemple :

<a href="./rumeur.php?r=Brumevent>Brumevent</a> est une région brumeuse et venteuse.

Si tu veux pas appeler directement un script php, tu peux faire référence à une fonction AJAX qui fait un XHR, enfin ça c'est toi qui voit.
(ça doit pas être très MVC comme approche... Smile )

2. Pour les mots composés, tu peux ouvrir ta string $rumeur, remplacer tous les espaces par des _ et ensuite tu fais une recherche sur littoral_méridionnal qui sera également ton index. C'est un process un peu complexe mais si tu le fais une fois c'est pas la mort.

ça m'intéresse quand tu auras trouver la solution parce que je veux faire pareil pour un système d'aide.


RE: recherche de mots - gtsoul - 14-02-2007

Je ne veux rien stocker, je cherche à faire des regex (mais je suis une daube en regex) du style :
sélectionner tous les sujets qui comportent "meridionnal", même en partie. Puis l'optimiser en recherchant tous les sujets qui contiennent au moins un mot (définis par deux espaces et hors d'une liste de mots communs, le la les et du) qui soit compris dans la bdd.

D'abord en php simple, puis je broderai du ajax par dessus.

(mvc, je l'utilise de temps en temps ; mais dans le cas présent en php, ca risque de bien plomber mes perfs et mutliplier par 3 mon nombre de classes. Langage non-compilé : pas de mvc pur)


RE: recherche de mots - denisc - 14-02-2007

Et pourquoi pas une classe statique qui contiendrai (chargerai) la liste des mots clé de rumeur ainsi qu'une fonction "generate_links" => Tu passe en paramètre le texte de ta rumeur, il te retourne une autre chaine avec les biens <a></a> inclus dans le texte en fonction de son dictionnaire... Reste plus qu'à afficher le résultat!


RE: recherche de mots - Seren - 15-02-2007

En fait tu veux juste éviter de regarder chaque mot dans ta chaîne de character.

Tu peux utiliser les fonction ereg(), eregi() et plus important ereg_replace() qui te permettra de finallement remplacer ton mot par le lien.

la syntaxe est assez simple :
Code PHP :
<?php 
$mot
= meridional;
$pattern = ' '.$mot.' '; // tu cherches le pattern de ton mot précédé et suivi par un espace
$replace = "<a href="..\rumeur.php?p=".$mot."\">".$mot."</a>"
$rumeur = ereg_replace($pattern, $replace, $rumeur);

ça ouvre la chaîne $rumeur, ça cherche une occurence du pattern. C'est une regexp basique, il y a aucun caractère spéciale. Tu veux exactement ton mot, tu tappes exactement ton mot.

Et ensuite à chaque fois qu'il trouve le pattern, il le remplace par quelque chose de ton choix.

De cette façon, tu n'as pas besoin de découper le texte en mot et de comparer ensuite chaque mot. En pratique c'est ce que va faire la fonction mais on peut espérer que ce soit un peu optimisé. Smile

Par contre t'es obligé d'utiliser cette procédure pour tous les mots de ta liste je vois pas trop comment c'est possible autrement.

Plus d'explication.
http://us2.php.net/manual/fr/function.ereg-replace.php


( Si t'as vraiment des gros textes avec des milliers de mots, tu peux essayer de faire une table de hachage, ça réduira déjà le nombre de mot que tu devras vérifier. Mais ça implique que tu fasses tout manuellement sans utiliser ereg et compagnie. )


RE: recherche de mots - denisc - 15-02-2007

Ou alors un système qui crée les liens au moment où tu ajoutes les nouvelles rumeurs...

Ta table :
[rumeurs]
id_rumeur
lib
texte
htm

où lib est le mot, texte est le texte de la rumeur et htm le texte transformé avec les liens...

Procédure:
1.J'ajoute la nouvelle rumeur en BD
2.Je charge la liste des lib(s) et leur associe leur id_rumeur (tableau du genre mot[id_rumeur]=lib)
3.Je relie chaque ligne texte de ma table et remplace toutes les occurences de chaque mot[] par '<a href=".......?id_rumeur=id_rumeur>lib</a>' que je met dans le champ
htm
4.c'est fini
Au moment du display, je n'utilise que le champ htm...


RE: recherche de mots - gtsoul - 15-02-2007

@ seren, j'utilise split qui me permet de parser une phrase selon les espaces et me renvoie un tableau de mots

il n'y pas en sql une fonction qui permet de comparer les éléments communs à deux ensembles :
d'un côté j'ai mon tableau php de mots et de l'autre un "SELECT nom FROM rumeur", comment faire pour ne sortir que les éléments compris à la fois dans le tableau et à la fois dans la sous-requete ?

"SELECT nom FROM rumeur WHERE nom IN $tableau_mots"; comme array_search mais en sql


RE: recherche de mots - Seren - 15-02-2007

http://dev.mysql.com/doc/refman/5.0/en/string-functions.html

SELECT List.nom, Rumeur.id
FROM Rumeur, List
WHERE LOCATE(List.nom, Rumeur.Description)

ou

SELECT List.nom, Rumeur.id
FROM List
LEFT JOIN Rumeur ON LOCATE(List.nom, Rumeur.Description)

Je suis absolument pas certain que ça marche, mais LOCATE renvoie 0 si il ne trouve pas la chaîne, et la position sinon.

Sachant que si le mot est au début de la description, l'index de SQL commence à 1.