[PHP] Supprimer les mots de moins de x caractères

  • Auteur de la discussion Auteur de la discussion Bobez
  • Date de début Date de début
WRInaute impliqué
Bonjour,

Existe-t-il un moyen simple de supprimer les mots de moins de x caractères se trouvant dans une chaîne, sans passer par une solution alternative (en utilisant une boucle for) ? Je me dis que ça doit être faisable avec les expressions régulières, mais je n'arrive pas à grand chose :wink:

Merci !
 
WRInaute impliqué
le problème se situe dans les lettres accentuées etc. Elles sont composées comment tes chaines exactement ?
 
WRInaute impliqué
En ce qui concerne les caractères accentuées, je m'en débarasse avant, ça ne pose pas de problème !
Imaginons une chaine de mots toute simple type : "L'arbre est beau".
Il faudrait supprimer de ça tous les mots de moins de 4 lettres, donc il resterait "l'arbre beau". Le must du must serait qu'il ne reste plus que "arbre beau", mais je sens que ça va pas être facile ! Au pire je peux faire un str_replace() après pour virer ce genre de choses.
 
WRInaute passionné
eregi = caca ;)

A part ça, ça va poser problème pour les mots qui sont en début ou fin de phrase. Donc je pense qu'il va falloit jouer avec \b et \w. Je regarde de mon côté si je trouve quelque chose d'efficace.

Fred
 
WRInaute impliqué
Ben je veux bien, si c'est un truc simple ! Car si le code est long, avec une boucle for() et tout, c'est pas la peine, j'avais trouvé comment faire, je cherche vraiment un truc simple ! :)
 
WRInaute impliqué
Ça fonctionne, et ça n'est pas très lourd en code ! J'ai le droit de mettre ici la version finale ?
 
WRInaute impliqué
Ah oui effectivement 8O Mais je n'arrive pas à l'adapter pour virer les mots de moins de 4 caractères...je suis vraiment une quiche en regex :P
 
WRInaute accro
Je te conseille ( pour l'avoir fait pour mon site http://www.retronimo.com ) d'utiliser les expressions régulières comme mentionné plus haut.

Ton code pourra ressembler à
$mots = eregi_replace ($patern, " ", $mots);
où $patern est la variable contenant la formule de l'expression régulière, du type
$patern = "[^a-z |^0-9|^é|^è|^ê|^à|^ô|^ù|^ç]";
Dans ton cas, le $partern ne doit pas être trop difficile à écrire.

Voir un tutorial pour la construire : http://www.phpfrance.com/tutorials/index.php?id=22 (pour ma part, je découvre seulement les expressions régulières, c'est déroutant au début mais ça peut s'avérer très utile).
 
WRInaute impliqué
Comme l'avait dit Georges, ce code pose problème si cela concerne le premier mot : il n'est pas remplacé. Je suppose qu'il faudrait rajouter quelque chose dans le regex pour le premier mot (avec ^) mais je dois dire que je n'y arrive pas...
Je continue à chercher, mais si qqun peut éclairer ma lanterne, qu'il n'hésite pas :wink:
 
WRInaute impliqué
Bon! J'ai réussi à le faire en utilisant deux regex de suite.

Code:
Suppression des mots de moins de 4 lettres :
$chaine = ereg_replace('^.{1,3} ', ' ', $chaine);
$chaine = ereg_replace(' .{1,3} ', ' ', $chaine);

Par contre, cela crée un espace en début de chaine, donc il faut utiliser trim() ensuite pour le supprimer.

Si quelqu'un parvient à faire ça en un seul regex (et sans trim)...chapeau :)
 
WRInaute impliqué
En fait cela ne fonctionne pas ! :twisted: Si plusieurs mots de moins de 4 lettres se suivent ça n'efface que le premier ! Help :(
 
WRInaute impliqué
Ok , voici le code PHP qu'utilise phpBB légèrement allégé ( au moins c'est sûr que ça marche ! ) :
Code:
$drop_char_match =   array('^', '$', '&', '(', ')', '<', '>', '`', '\'', '"', '|', ',', '@', '_', '?', '%', '-', '~', '+', '.', '[', ']', '{', '}', ':', '\\', '/', '=', '#', '\'', ';', '!');
$drop_char_replace = array(' ', ' ', ' ', ' ', ' ', ' ', ' ', '',  '',   ' ', ' ', ' ', ' ', '',  ' ', ' ', '',  ' ',  ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' , ' ', ' ', ' ', ' ',  ' ', ' ');
$entry = ' ' . strip_tags(strtolower($entry)) . ' ';
$entry = preg_replace('/[\n\r]/is', ' ', $entry); 
$entry = preg_replace('/\b&[a-z]+;\b/', ' ', $entry); 
$entry = preg_replace('/\b[a-z0-9]+:\/\/[a-z0-9\.\-]+(\/[a-z0-9\?\.%_\-\+=&\/]+)?/', ' ', $entry);
for($i = 0; $i < count($drop_char_match); $i++)
{
	$entry =  str_replace($drop_char_match[$i], $drop_char_replace[$i], $entry);
}
$entry = str_replace('*', ' ', $entry);
$entry = preg_replace('/[ ]([\S]{1,2}|[\S]{3})[ ]/',' ', $entry);
où $entry est ta chaine de caractères .
 
WRInaute impliqué
Wow 8O Ils font pas dans la dentelle, c'est quand même un peu brutos !
Dans mon cas, les chaînes sont assez spécifiques et je pense que la soluce de George marche parfaitement (je verrai par la suite si je détecte des anomalies).
Cela dit, dans un cas plus complexe/général, ce code est sans doute plus sûr, je le note okazou :wink: Merci !
 
WRInaute impliqué
À propos du code de George :

Code:
preg_replace('/\b[^ ]{1,3}\b/', '', $chaine);
Il marche parfaitement, le seul truc c'est qu'il est possible que j'aie à faire à des caractères autres que des lettres. Et là, dans ce cas, si par exemple j'ai la chaine "blabla - blablabla", il va me laisser le tirêt du milieu.

Y-a-t-il une petite astuce pour que ce code s'applique à tous les types de caractères ? C'est affreux, j'ai vraiment du mal avec ces regex, surtout quand c'est des preg_replace() !

Merci beaucoup
 
WRInaute impliqué
Bienvenue et merci de consacrer ton 1er post pour m'aider :)
Par contre, le tiret était un exemple parmi d'autres, en fait je risque d'avoir affaire à beaucoup de caractères...donc si qqun a une solution qui fonctionne dans un cadre plus général, je vous remercie d'avance !
 
Discussions similaires
Haut