Filtrer les mots

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Filtrer les mots

par Ripat » 23 août 2005, 11:48

Faut quand même que je tempère ton enthousiasme sur ta "méthode parfaite".
  • Faire un str_replace pour insérer une balise pour ensuite vérifier si cette balise existe, c'est se compliquer singulièrement la vie et gaspiller de précieuses ressources.
  • faire un foreach sur un tableau d'un seul élément, idem.
  • Au risque de me répéter (voir plus haut) la technique du str_replace pour détecter des mots ne convient pas pour des phrases normalement constituées (avec de la ponctuation). Dans ton code, si tu interdis - à juste titre - le mot cul (pardon, mais c'est pour l'exemple... :oops: ), une phrase parlant d'agriculture sera censurée.
  • détecter, sans omission, tous les gros mots n'est déjà pas très facile (il faut les prévoir tous) mais, mettre en évidence l'utilisation d'un language sms, va te donner *beaucoup* de travail!
Relis et surtout essaye de bien comprendre l'utilisation des tableaux et de la regex donnée plus haut et tu trouveras une solution presque convenable.

par enki » 22 août 2005, 21:52

Ca y est ! J'ai trouvé une méthode parfaite !!
On sait que la méthode 'remplacement' est très éfficace. Si on écrit xxcretinxxx, alors ce mot est censuré quand meme.

Comme je souhaite absolument la méthode de Ripat avec exit (mais qui a une faille), il suffit alors de combiner les 2 !

Je commence à remplacer les mots indésirables par # BAN # :
$banwords = Array('otre ke','elle et tro ','é tro ','né pas','c tro ','cé pa ',' ossi','pouvé','kestion','kon','fodra','pk','batar','cretin','idiot','AJOUTER AUTRES GROS MOTS ICI');
$message = str_replace($banwords, '# BAN #', $message);
Maintenant que les mots indésirables ont été remplacé par BAN avec espaces autour, ca ne posera plus de problème. Je mets le script de Ripat à la suite :
$banwords = array('BAN');
foreach ($banwords as $v){ 
$motif = '#\b'.$v.'\b#';
if (preg_match($motif, $message)) {
echo "Le langage SMS et les insultes sont interdits";
print("<p><a href=\"javascript:history.back()\">Retour</a>");
exit; }
}
Voilà, c'est génial maintenant ! Comme 9 messages sur 10 sur mon forum sont des messages écrits en sms, je gagne un temps considérable !
Merci à vous tous !

par Cyrano » 21 août 2005, 17:11

Il ne faut pas confondre les variables: $texte est ici définie dans le foreach et initialisée avec les valeurs du tableau $grosmots. Donc à chaque tour de la boucle, la valeur est ré-initialisée avec l'élément suivant du tableau.
Shématiquement, on pourrait écrire avec des variables plus "parlantes" foreach($tableau as $valeur). Tu pourrais même extraire les index avec foreach($tableau as $index => $valeur). Dans un tableau du genre
<?php
$tableau = array('a','b','c','d');
foreach($tableau as $index =>$valeur)
{
    echo("<p>L'élément ". $index ." du tableau \$tableau est ".  $valeur."</p>\n");
}
?>
Ce code va afficher:
L'élément 0 du tableau $tableau est a

L'élément 1 du tableau $tableau est b

L'élément 2 du tableau $tableau est c

L'élément 3 du tableau $tableau est d
Ensuite, au lieu d'un exit(), génère des messages d'avertissement et au lieu d'arrêter la page pour ne pas afficher le reste, gère le contenu que tu veux afficher pour fermer normalement le code de la page.

par enky » 21 août 2005, 14:40

C'est justement ce que je veux, arrete la page d'afficher s'il y a un gros mot trouvé dans $message :

echo "insultes interdits";
print("<p><a href=\"javascript:history.back()\">Retour</a>");
exit;

J'ai placé ton script juste après la validation du message. Là où je placais le script du remplacement de mot.

Je comprends pas d'où sort la variable $texte. Et pourquoi c'est pas la variable $message qui est comparé avec $grosmot ?

par Cyrano » 21 août 2005, 14:05

exit() arrête l'application, je ne suis pas certain que ce soit le but du jet sur une page web parce que ça arrête aussi la génération de la page qui sera donc incomplète.

Quant au fonctionnement sur le message envoyé, ça me parait curieux: comment as-tu testé ces lignes ?

par enky » 21 août 2005, 13:49

Ca ne marche que sur tes 2 exemples. Mais pas sur le message posté : $message

Et puis, il ne fait pas exit;

par Cyrano » 21 août 2005, 12:28

Pour la première, tu fais un nettoyage avec str_replace mais ça ne sert à rien puisque si un des mots bannis est trouvé, ça arrête l'application ensuite. Shéma pas vraiment logique.

Pour la seconde formulation, ereg() attends une expression rationnelle en premier paramètre et tu lui mets une chaine directe. Essaye comme ceci:
<?php
function censure($msg)
{
    $grosmot = array('cretin', 'crétin','imbecile', 'imbécile','idiot');
    $nb_gm = 0;
    foreach ($grosmot as $texte)
    {
        $texte = "^.*(". $texte .")e?.*$";
        if(ereg ($texte,$msg))
        {
            $nb_gm++;
        }
    }
    $message = ($nb_gm > 0) ? ("<p>Mots interdits trouvés dans le texte soumis, message censuré !</p>") : "<p>". $msg ."</p>\n";
    return $message;
}
$message1 = "Ce type est le plus parfait imbécile et sa femme est l'idiote du village";
$message2 = "Ce type est le plus parfait gentleman et sa femme est la meilleure des hôtesses";

echo(censure($message1));
echo(censure($message2));
?>

par enky » 21 août 2005, 11:53

J'ai pensé à ces quelques méthodes qui ne marche pas :
$grosmot = Array('cretin','imbecile','idiot'); 
$messagepropre = str_replace($grosmot, '***censuré***', $message); 
if ($message != $messagepropre) exit;
-> problème : ca fait exit dès le chargement de la page.

$grosmot = array('cretin','imbecile','idiot');
foreach ($grosmot as $texte) {
$comparaison = ereg ($message,$texte);
if($comparaison) exit();
}
-> message d'erreur à la ligne $comparaison = ereg ($message,$texte);

Quelqu'un pour me corriger ? :-k

par enky » 20 août 2005, 19:32

Pourtant, la méthode de remplacement marche très bien :

$grosmot = Array('cretin', 'idiot', 'imbecile');
$message = str_replace($grosmot, '**censuré**', $message);

Si on écrit cretine, alors ca affiche : **censuré**e

Aucun problème !

Pourquoi la méthode de exit ne marche pas comme ça ?

Il n'y a pas un moyen de vérifier au mileu d'un mot ?

Par exemple, vérifier que ce message ne contient pas de gros mot : xxxx xxx xxxcretinxxx xxx xxx

PS : J'insiste sur la méthode d'exit (celle de Ripat), elle est vraiment bien. Ca me fait gagner un temps considérable.

par Ripat » 20 août 2005, 11:00

:shock:

Ben, oui, évidemment. Si le mot interdit ne se trouve pas dans le tableau de départ....

Un petit coup de pouce pour les féminins:
$banwords = array('cretine?', 'idiote?', 'imbecile?'); 
Le e est rendu optionnel.

par enky » 19 août 2005, 19:25

$banwords = array('cretin', 'idiot', 'imbecile');

// le plus court:
$motif = '#\b(?:'.implode('|', $banwords).')\b#i';
if (preg_match($motif, $message)){
  exit;
}

// le plus efficace
foreach ($banwords as $v){
  $motif = '#\b'.$v.'\b#i';
  if (preg_match($motif, $message)){
    exit;
  }
}
Je me suis rendu compte de l'inéfficacité de ce script.
En effet, il suffit que les gens écrivent idiote à la place de idiot pour que ca ne soit pas pris en compte.

Pourtant le script du remplacement ne connait pas ce problème.

par Ripat » 12 août 2005, 20:29

par enky » 12 août 2005, 16:36

oui, j'ai déjà testé avant. Ca marche, mais je ne comprends pas la signification de ce i.

par raptor » 12 août 2005, 12:34

Le mieux est de tester, ca prend 2 secondes en plus.

par enky » 12 août 2005, 12:31

Donc dans
$motif = '#\b'.$v.'\b#i';

j'enlève tout simplement le i ?

ce qui donne
$motif = '#\b'.$v.'\b#';

C'est tout ?