[PHP] Ajouter une exception dans une regex

WRInaute discret
Bonjour,

Je chercher à améliorer un script que j'utilise sur un de mes sites.

Ce script à pour but d'extraire via un explode des mots compris dans une chaine de caractères de type : sans-wri-j-aurais-fais-souvent-nimporte-quoi-avec-google. Cette variable est prise aléatoirement dans une bdd

Dans un premier temps, je vire les mots usuels comme, sans, fais ... :
Code:
$chaine = str_replace(array('sans', 'fais', quoi'), '', $chaine);

Puis je retire tous les mots de 3 lettres et moins :
Code:
$chaine = eregi_replace("-(.{1,3}-)+|^(.{1,3}-)+|(-.{1,3})+$","-",$chaine);

Mais, je voudrais que certains mots de 3 lettres compris dans un array précis ne soit pas supprimés s'ils sont présents dans la chaine initiale comme wri par exemple.

Tout ce que j'ai essayé n'a pas donné l'effet escompté :oops:

Une idée ?

Merci
 
Nouveau WRInaute
Il existe certainement une solution bien plus gracieuce, en voici une craceuse qui m'est venue à l'esprit :)

Si ton tableau de mot spéciaux n'est pas trop grand. Tu mets tes mots de 3 lettres dans un tableau.
Avant de faire ta regex, tu parcours ce tableau et tu leurs mets un suffixe, par exemple "MOTSPECIAL".
Tu appliques ta regex.
Puis tu convertis ta chaine en supprimant MOTSPECIAL de ta chaine.

C'est pas beau, mais à mon avis ça devrait fonctionner.
 
WRInaute accro
D'abord:
- ton str_replace va replacer des parties de mots aussi, par exemple persans -> per, faisant -> ant, pourquoi -> pour... Utilise soit une regex avec des \b autour, soit un explode et un traitement mot par mot
- tu peux simplifier ta regex en utilisant par exemple \b\w{1,3}\b (en utilisant preg_replace plutôt que eregi_replace, et en n'oubliant pas d'ajouter des délimiteurs). Ou utiliser une explode là aussi.
- de façon générale, utilise plutôt les preg_* que les ereg*

Si tu fais un explode, le traitement des mots spéciaux n'est pas difficile (il suffit de les tester avant de faire le test sur la longueur des mots). Si tu veux vraiment une regex, il va falloir utiliser une negative look-ahead assertion (preg_replace only):

'/\b(?!(?:mot_ok1|mot_ok2|mot_ok3)\b)\w{1,3}\b/'

Jacques.
 
WRInaute passionné
photoscope a dit:
Il existe certainement une solution bien plus gracieuce, en voici une craceuse qui m'est venue à l'esprit :)

Si ton tableau de mot spéciaux n'est pas trop grand. Tu mets tes mots de 3 lettres dans un tableau.
Avant de faire ta regex, tu parcours ce tableau et tu leurs mets un suffixe, par exemple "MOTSPECIAL".
Tu appliques ta regex.
Puis tu convertis ta chaine en supprimant MOTSPECIAL de ta chaine.

C'est pas beau, mais à mon avis ça devrait fonctionner.

J'ai longtemps cherché une solution pour emp^cher le traitement par une REGEX.
Depuis, je me prend plus la tête.

Quand je traite ma chaîne, j'insère sur les termes qui ne doivent pas être traités plus tard par une regex, un "§§" (exemple§§)

J'ai choisi ce signe, car pratiquement aucune chance de le retrouver dans un texte.

Quand j'ai fini mes traitement, un petit str_replace sur mon "§§" et le tour est joué.

Maintenant, si tu trouves une autre solution, moins gourmande, je suis preneur.
 
Discussions similaires
Haut