Précédent   Forum des professionnels en informatique > PHP > Langage > Regex
Regex Forum d'entraide sur les expressions rationnelles PHP. Avant de poster -> FAQ regex, Cours de regex et Sources de regex
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 02/11/2011, 08h51   #1
Membre à l'essai
 
Inscription : mai 2007
Messages : 98
Détails du profil
Informations forums :
Inscription : mai 2007
Messages : 98
Points : 20
Points : 20
Par défaut Regex permettant de retourner la liste des mots

Bonjour,

Je dois zapper un truc "tout con", mais avec un preg_match_all, je souhaite créer un table qui contient la liste des mots d'une chaîne de caractères en supposant également que plusieurs espaces doivent compter comme un seul !

Ainsi la chaîne suivante :
Citation:
"Voici un texte ou certains mots sont séparés de plusieurs espaces"
devra me retourner le tableau suivant :
Citation:
Array
(
[0] => "Voici"
[1] => "un"
[2] => "texte"
[3] => "ou"
[4] => "certains"
[5] => "mots"
[6] => "sont"
[7] => "séparés"
[8] => "de"
[9] => "plusieurs"
[10] => "espaces"
)
Mais j'arrive pas a trouver la bonne regex permettant de faire considérer plusieurs espaces comme un seul
elekaj34 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/11/2011, 11h21   #2
Membre confirmé
 
Homme Lionel Chaumeau
Développeur Web
Inscription : octobre 2011
Messages : 75
Détails du profil
Informations personnelles :
Nom : Homme Lionel Chaumeau
Localisation : France, Puy de Dôme (Auvergne)

Informations professionnelles :
Activité : Développeur Web
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : octobre 2011
Messages : 75
Points : 264
Points : 264
Hello,
Tu peux aussi faire les choses en deux étapes:
réduire les espaces successifs >1 en ' ':
Code :
$texte = preg_replace('/\s{2,}/', ' ', $texte);
cf sujet sur forum
et ensuite, tu peux faire un explode .
NB: A mon avis, tu dois pouvoir aussi tout faire directement avec preg_split mais je ne l'ai jamais encore utilisée...
__________________
My laptop, my bike and my double-sticks...
kalimukti est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/11/2011, 11h32   #3
Modérateur
 
Inscription : septembre 2010
Messages : 7 156
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 156
Points : 8 524
Points : 8 524
str_word_count ?
__________________
http://blog.stealth35.com/
stealth35 est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/11/2011, 12h00   #4
Membre à l'essai
 
Inscription : mai 2007
Messages : 98
Détails du profil
Informations forums :
Inscription : mai 2007
Messages : 98
Points : 20
Points : 20
Re,

J'ai utilisé ce bricolage,

Code :
1
2
$texte="Voici un texte   ou  certains mots sont séparés de plusieurs espaces";
$out=array_slice(array_unique(explode(" ",$texte)),0);
c'est pas parfais, convient largement à mon besoin

Par contre, je pensais (naïvement) pouvoir faire cela proprement avec une regex et un simple preg_match
elekaj34 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/11/2011, 13h14   #5
Membre confirmé
 
Homme Lionel Chaumeau
Développeur Web
Inscription : octobre 2011
Messages : 75
Détails du profil
Informations personnelles :
Nom : Homme Lionel Chaumeau
Localisation : France, Puy de Dôme (Auvergne)

Informations professionnelles :
Activité : Développeur Web
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : octobre 2011
Messages : 75
Points : 264
Points : 264
Citation:
Envoyé par elekaj34 Voir le message

Par contre, je pensais (naïvement) pouvoir faire cela proprement avec une regex et un simple preg_match
résultat plus propre (sans un resultat avec un chaine vide, comme dans ton code), avec regex:
Code :
1
2
3
$texte="Voici un texte  ou   certains mots sont séparés de plusieurs espaces";
$out=preg_split("/[\s]+/", $texte);
var_dump($out);
__________________
My laptop, my bike and my double-sticks...
kalimukti est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/11/2011, 13h20   #6
Modérateur
 
Inscription : septembre 2010
Messages : 7 156
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 156
Points : 8 524
Points : 8 524
Code :
1
2
$texte="Voici un texte  ou   certains mots sont séparés de plusieurs espaces";
$out = str_word_count($texte, 1);
__________________
http://blog.stealth35.com/
stealth35 est actuellement connecté   Envoyer un message privé Réponse avec citation 10
Vieux 02/11/2011, 13h28   #7
Membre confirmé
 
Homme Lionel Chaumeau
Développeur Web
Inscription : octobre 2011
Messages : 75
Détails du profil
Informations personnelles :
Nom : Homme Lionel Chaumeau
Localisation : France, Puy de Dôme (Auvergne)

Informations professionnelles :
Activité : Développeur Web
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : octobre 2011
Messages : 75
Points : 264
Points : 264
Citation:
Envoyé par stealth35 Voir le message
Code :
1
2
$texte="Voici un texte  ou   certains mots sont séparés de plusieurs espaces";
$out = str_word_count($texte, 1);
ouai en effet
marche aussi pour des séparateurs genre ',', '/'... en plus on peut paramétrer le retour... merci stealth (connaissait po )
__________________
My laptop, my bike and my double-sticks...
kalimukti est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/11/2011, 14h03   #8
Membre à l'essai
 
Inscription : mai 2007
Messages : 98
Détails du profil
Informations forums :
Inscription : mai 2007
Messages : 98
Points : 20
Points : 20
La version avec str_word_count marche .... a peu près (chez moi les accents sont comptés comme séparateur).

Sinon, la soluce de kalimukti marche au poil

Merci à vous
elekaj34 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/11/2011, 00h54   #9
Membre du Club
 
Homme Boris
conception et traitement de documents xhtml
Inscription : août 2011
Messages : 107
Détails du profil
Informations personnelles :
Nom : Homme Boris
Localisation : France, Seine et Marne (Île de France)

Informations professionnelles :
Activité : conception et traitement de documents xhtml
Secteur : Conseil

Informations forums :
Inscription : août 2011
Messages : 107
Points : 59
Points : 59
Bonjour,

Je ne connaissais pas non plus str_word_count. J'essaierai

Par contre, j'utilise preg_split avec un bon paquet de délimiteurs :
Code :
1
2
$regex = '#[ ,/\&\"\#\'\{\(\[\-\|\_\\\^\@\)\]\=\+\}\$\%\*\<\>\?\;\.\:\!]+#Us';
$words = preg_split($regex, $value, -1, PREG_SPLIT_NO_EMPTY);
Doc_xhtml est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/11/2011, 10h02   #10
Modérateur
 
Inscription : septembre 2010
Messages : 7 156
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 156
Points : 8 524
Points : 8 524
Citation:
Envoyé par Doc_xhtml Voir le message
Bonjour,

Je ne connaissais pas non plus str_word_count. J'essaierai

Par contre, j'utilise preg_split avec un bon paquet de délimiteurs :
Code :
1
2
$regex = '#[ ,/\&\"\#\'\{\(\[\-\|\_\\\^\@\)\]\=\+\}\$\%\*\<\>\?\;\.\:\!]+#Us';
$words = preg_split($regex, $value, -1, PREG_SPLIT_NO_EMPTY);
\b est le délimiteur de mot, suffit de rajouter - et ', et c'est ok
__________________
http://blog.stealth35.com/
stealth35 est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/11/2011, 10h32   #11
Membre du Club
 
Homme Boris
conception et traitement de documents xhtml
Inscription : août 2011
Messages : 107
Détails du profil
Informations personnelles :
Nom : Homme Boris
Localisation : France, Seine et Marne (Île de France)

Informations professionnelles :
Activité : conception et traitement de documents xhtml
Secteur : Conseil

Informations forums :
Inscription : août 2011
Messages : 107
Points : 59
Points : 59
Merci Stealth de ta suggestion

Effectivement, il y avait plus simple que d'énumérer tous les séparateurs du clavier.
(Je voulais permettre à l'utilisateur de définir en toute liberté ses propres séparateurs.)

Je corrigerai mon code en conséquence.
Doc_xhtml est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/12/2011, 00h32   #12
Membre du Club
 
Homme Boris
conception et traitement de documents xhtml
Inscription : août 2011
Messages : 107
Détails du profil
Informations personnelles :
Nom : Homme Boris
Localisation : France, Seine et Marne (Île de France)

Informations professionnelles :
Activité : conception et traitement de documents xhtml
Secteur : Conseil

Informations forums :
Inscription : août 2011
Messages : 107
Points : 59
Points : 59
Citation:
Envoyé par stealth35 Voir le message
\b est le délimiteur de mot, suffit de rajouter - et ', et c'est ok
Bonjour Stealth,

Il y a peut-être quelque chose que je n'ai pas compris.
Lorsque j'utilise l'ancienne regex, le code ci-dessous me génère bien la table des mots.
Code :
1
2
$regex = "#[ ,/\&\"\#\'\{\(\[\-\|\_\\\^\@\)\]\=\+\}\$\%\*\<\>\?\;\.\:\!]+#Us";
$words = preg_split($regex, $value, -1, PREG_SPLIT_NO_EMPTY);
Par contre, lorsque je simplifie la regex en utilisant \b,
Code :
1
2
$regex = "#[\b\-\']+#Us";
$words = preg_split($regex, $value, -1, PREG_SPLIT_NO_EMPTY);
$words[0] contient la chaîne $value entière mais la table des mots n'est pas générée.

Où est l'erreur ?
Doc_xhtml est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/12/2011, 01h13   #13
Membre Expert
 
Avatar de Djakisback
 
Inscription : février 2005
Messages : 1 791
Détails du profil
Informations forums :
Inscription : février 2005
Messages : 1 791
Points : 1 681
Points : 1 681
Salut,
c'est dû au fait que tu le mettes entre crochets, du coup le pattern match la 'classe mots'. Par contre, t'auras les espaces considérés comme des mots avec ce pattern.

(\b est dépendant de l'encoding et str_word_count() de la localisation définie, il vaut mieux définir le pattern sur le split plutôt que sur ce que tu veux conserver)
__________________
Vive les roues en pierre
Djakisback est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/12/2011, 23h14   #14
Membre du Club
 
Homme Boris
conception et traitement de documents xhtml
Inscription : août 2011
Messages : 107
Détails du profil
Informations personnelles :
Nom : Homme Boris
Localisation : France, Seine et Marne (Île de France)

Informations professionnelles :
Activité : conception et traitement de documents xhtml
Secteur : Conseil

Informations forums :
Inscription : août 2011
Messages : 107
Points : 59
Points : 59
Citation:
Envoyé par Djakisback Voir le message
c'est dû au fait que tu le mettes entre crochets, du coup le pattern match la 'classe mots'. Par contre, t'auras les espaces considérés comme des mots avec ce pattern.
Merci de ta réponse, Djakisback.

J'avoue ne pas bien comprendre. Dans les exemples de preg_split, on trouve des expressions du type
Code :
preg_split("/[\sautres_caractères_de_séparation]+/", chaîne)
En quoi sur le fond le délimiteur \b diffère-t-il du délimiteur \s ? Pourquoi ne peut-on pas le mettre entre crochets ?
J'ai essayé la syntaxe
Code :
preg_split("#\b#", chaîne)
J'obtiens une table contenant les mots, mais aussi les espaces, les délimiteurs tels que / ainsi que les caractères accentués qui sont considérés comme délimiteurs (mais non affichés par print_r).

Citation:
Envoyé par Djakisback Voir le message
(\b est dépendant de l'encoding et str_word_count() de la localisation définie, il vaut mieux définir le pattern sur le split plutôt que sur ce que tu veux conserver)
Excuse-moi, je n'ai pas vraiment compris ce que tu veux transmettre.
Doc_xhtml est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/12/2011, 20h59   #15
Membre Expert
 
Avatar de Djakisback
 
Inscription : février 2005
Messages : 1 791
Détails du profil
Informations forums :
Inscription : février 2005
Messages : 1 791
Points : 1 681
Points : 1 681
Finalement, je ne m'explique pas pourquoi \b défini dans une classe via les crochets ne matche pas les délimiteurs de mots. En tout cas avec :

Code :
$out = preg_split("/[\b]/Us", $texte);
aucun délimiteur n'est matché, donc preg_split() retourne la chaîne complète, de la même manière que :

Code :
preg_match_all("/[\b]/Us", $texte, $out);
ne retourne aucun résultat.

Au sujet de :

Code :
preg_split("#\b#", chaîne)
c'est ce que je disais à propos de l'encoding. Par défaut, seuls les caractères de la classe [a-zA-Z0-9_] sont considérés comme des caractères de "mot", l'ASCII non étendu en fait, si je ne m'abuse.
On peut utiliser l'option /u pour analyser les caractères en tant qu'UTF-8.

Le problème est quasiment le même avec str_word_count() qui lui, analyse les chaînes en fonction de la locale définie, mais qui en plus va bugger si c'est de l'UTF-8 car il ne gère pas le multibytes il me semble.

Ce que je voulais dire par ma dernière phrase c'est qu'à mon avis utiliser un pattern de ce type (donc comme tu le faisais) :

Code :
1
2
$out = preg_split("/[\s;:,!)(etc.]+/", $texte, null, PREG_SPLIT_NO_EMPTY);
c'est à dire travailler sur ce qu'on veut splitter et non pas sur la notion de 'mot', me semble beaucoup plus portable si on excepte certaines langues particulières comme le Japonais, etc. Un avis personnel bien sûr

(une autre soluce serait de forcer l'utf-8 et d'utiliser plutôt match_all afin de ne pas récupérer les espaces et délimiteurs dans le tableau final comme c'est le cas avec $out = preg_split("/\b/Uu", $texte) :
Code :
preg_match_all("`\w+?`Uu", $texte, $out);
)
__________________
Vive les roues en pierre
Djakisback est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/12/2011, 09h25   #16
Modérateur
 
Inscription : septembre 2010
Messages : 7 156
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 156
Points : 8 524
Points : 8 524
je te déconseille fortement d’utiliser l'opérateur d'exécution (`) pour délimiter tes regex
__________________
http://blog.stealth35.com/
stealth35 est actuellement connecté   Envoyer un message privé Réponse avec citation 11
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 12h40.


 
 
 
 
Partenaires

Hébergement Web