Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Vérifier la présence d'un mot dans tous les champs

1 view
Skip to first unread message

Olivier Miakinen

unread,
Mar 13, 2022, 2:19:01 PM3/13/22
to
Bonjour,

D'habitude c'est le plus souvent moi qui donne la solution à un problème
de regexp, mais pour une fois c'est moi qui ai besoin d'aide.

Dans une phrase comportant plusieurs mots séparés entre autres par des
virgules, je voudrais vérifier qu'un mot en particulier se trouve dans
chaque partie de la phrase.


Par exemple, pour le mot cœur, cette phrase serait valide :

Pour parler à cœur ouvert, cœur à cœur, je mets du cœur à l'ouvrage,
même si ce n'est pas de gaieté de cœur.


En revanche celle-ci ne serait pas valide :

Pour parler à cœur ouvert, cœur à cœur, je mets beaucoup de courage,
même si ce n'est pas de gaieté de cœur.

En effet, il n'y a nulle part le mot cœur entre la deuxième virgule
et la troisième virgule.


Je précise que ma variété de regexp est celle de Perl ou de PCRE
(Perl-compatible regular expressions).

Merci de votre aide !

--
Olivier Miakinen

Olivier Miakinen

unread,
Mar 13, 2022, 3:28:29 PM3/13/22
to
Le 13/03/2022 à 19:18, Olivier Miakinen j'écrivais :
>
> Dans une phrase comportant plusieurs mots séparés entre autres par des
> virgules, je voudrais vérifier qu'un mot en particulier se trouve dans
> chaque partie de la phrase.

J'ai peut-être une idée pour ça, et d'ailleurs j'ai posé la question
sous cette forme parce qu'elle me paraît un peu plus facile que ma
question d'origine qui est le contraire : vérifier qu'il existe au
moins l'une des parties de la phrase ne contenant *pas* ce mot.

> Par exemple, pour le mot cœur, cette phrase serait valide :
>
> Pour parler à cœur ouvert, cœur à cœur, je mets du cœur à l'ouvrage,
> même si ce n'est pas de gaieté de cœur.

Dans mon problème d'origine la phrase ne serait justement pas valide.

> En revanche celle-ci ne serait pas valide :
>
> Pour parler à cœur ouvert, cœur à cœur, je mets beaucoup de courage,
> même si ce n'est pas de gaieté de cœur.

Mais cette autre phrase le serait, grâce au segment « je mets beaucoup
de courage » qui ne contient pas le mot « cœur ».


--
Olivier Miakinen

Otomatic

unread,
Mar 14, 2022, 5:21:39 AM3/14/22
to
Olivier Miakinen <om+...@miakinen.net> écrivait :

> D'habitude c'est le plus souvent moi qui donne la solution à un problème
> de regexp, mais pour une fois c'est moi qui ai besoin d'aide.
Et c'est bien vrai ça !

Dans un tel cas, je ne chercherais pas une regexp, mais plutôt une
fonction avec explode pour séparer la phrase en segments et vérifier
dans chaque segment la présence ou non du mot.
En PHP :
> function trouve_mot($phrase,$mot) {
> $phrase_explode = explode(',',$phrase);
> foreach($phrase_explode as $value) {
> if(strpos($value,$mot) === false) {
> return false;
> break;
> }
> }
> return true;
> }

--
Un ordinateur résout des problèmes que nous n'aurions pas sans lui
Technique aéronautique : http://aviatechno.net

Olivier Miakinen

unread,
Mar 14, 2022, 5:47:31 AM3/14/22
to
Bonjour Dominique,

Le 14/03/2022 à 10:21, Otomatic m'a répondu :
>
> Dans un tel cas, je ne chercherais pas une regexp, mais plutôt une
> fonction avec explode pour séparer la phrase en segments et vérifier
> dans chaque segment la présence ou non du mot.

Oui, ce serait une bonne idée si c'était possible. Mais dans mon cas
précis il n'y a pas de moyen simple de modifier le code, seulement
les regexp. Je ne peux pas non plus capturer des sous-chaînes pour
les traiter séparément ensuite.

En revanche, j'ai la possibilité de combiner plusieurs regexp sur la
même chaine avec des opérateurs logiques. Quelques exemples :
- /regexp1/ et /regexp2/
- /regexp1/ ou /regexp2/
- non /regexp/
- non (/regexp1/ ou (/regexp2/ et non /regexp3/))

C'est pour ça que j'avais commencé par inverser le test, du fait que
ça me semblait plus facile, en effet je peux alors utiliser :
- non /regexp/
au lieu de :
- /regexp/

Quoi qu'il en soit, merci de ta réponse.

P.-S. : ton Forté Agent a toujours des problèmes avec les accents
dans les titres, alors j'y remplace mes é par des e.

--
Olivier Miakinen

Otomatic

unread,
Mar 14, 2022, 12:06:40 PM3/14/22
to
Olivier Miakinen <om+...@miakinen.net> écrivait :

> Oui, ce serait une bonne idée si c'était possible. Mais dans mon cas
> précis il n'y a pas de moyen simple de modifier le code, seulement
> les regexp.
Tu ne peux pas faire un truc du genre :
if nombre_virgule == nombre_cœur -> faux
ou
if nombre_cœur == (nombre_virgule + 1) -> vrai

Olivier Miakinen

unread,
Mar 14, 2022, 1:08:56 PM3/14/22
to
Le 14/03/2022 à 17:06, Otomatic a écrit :
>
>> Oui, ce serait une bonne idée si c'était possible. Mais dans mon cas
>> précis il n'y a pas de moyen simple de modifier le code, seulement
>> les regexp.
> Tu ne peux pas faire un truc du genre :
> if nombre_virgule == nombre_cœur -> faux
> ou
> if nombre_cœur == (nombre_virgule + 1) -> vrai

D'une part je ne sais pas écrire une regexp qui compte indépendamment
le nombre d'occurrences de deux chaînes et qui compare les deux
nombres. Mais d'autre part ce test ne serait pas le bon, puisqu'il
peut y avoir plusieurs fois le mot cœur entre deux virgules, et que
ça ne doit pas compenser le fait que ce mot manque entre deux autres
virgules.


Je rappelle mes deux exemples :

Pour parler à cœur ouvert, *cœur à cœur*, je mets du cœur à l'ouvrage,
même si ce n'est pas de gaieté de cœur.

Pour parler à cœur ouvert, *cœur à cœur*, je mets beaucoup de courage,
même si ce n'est pas de gaieté de cœur.

Dans le premier exemple il y a trois virgules pour cinq « cœur » alors
que dans le second exemple ce sont trois virgules et quatre « cœur ».


Pour enfoncer le clou, je peux dire que des deux phrases suivantes
l'une est valide et pas l'autre, alors qu'elles ont le même nombre
de chacun des deux éléments caractéristiques.

1) cœur,cœur,cœur,cœur
2) cœurcœur,,,cœurcœur

--
Olivier Miakinen

Olivier Miakinen

unread,
Mar 14, 2022, 4:20:19 PM3/14/22
to
Salut,

Je pense avoir trouvé pour les deux versions.

Le 13/03/2022 à 20:28, je me répondais :
>>
>> Dans une phrase comportant plusieurs mots séparés entre autres par des
>> virgules, je voudrais vérifier qu'un mot en particulier se trouve dans
>> chaque partie de la phrase.

La regexp suivante semble convenir :
/^[^,]*cœur[^,]*(,[^,]*cœur[^,]*)*$/

Elle a pour défaut de devoir écrire deux fois la chaîne à tester,
ici « cœur », mais elle n'a pas besoin de règles complexes telles
que les assertions.

>
> J'ai peut-être une idée pour ça, et d'ailleurs j'ai posé la question
> sous cette forme parce qu'elle me paraît un peu plus facile que ma
> question d'origine qui est le contraire : vérifier qu'il existe au
> moins l'une des parties de la phrase ne contenant *pas* ce mot.

Pour cette version, la regexp suivante a l'air d'aller :
/(^|,)([^,](?!cœur))*(,|$)/

Là au contraire j'ai besoin d'une assertion, mais la chaîne à tester
n'a besoin d'être écrite qu'une seule fois. Cela évite d'avoir à la
modifier à plusieurs endroits lors des phases de tests, ce qui évite
donc le risque de ne pas la modifier partout pareil.

Merci à Otomatic qui a tenté de m'aider, et... merci à moi pour
avoir finalement trouvé une solution. ;-)

--
Olivier Miakinen

Olivier Miakinen

unread,
Apr 5, 2022, 11:28:15 AM4/5/22
to
Bonjour,

Après vérifications et tests, je confirme que les deux regexp trouvées
fonctionnent comme prévu. Afin que ce groupe conserve un rôle pédago-
gique voici une explication pour chacune.


>>> Dans une phrase comportant plusieurs mots séparés entre autres par des
>>> virgules, je voudrais vérifier qu'un mot en particulier se trouve dans
>>> chaque partie de la phrase.
>
> La regexp suivante semble convenir :
> /^[^,]*cœur[^,]*(,[^,]*cœur[^,]*)*$/

On peut décomposer cette regexp en : /^RE(,RE)*$/
avec : RE=[^,]*cœur[^,]*

Chaque RE correspond à une chaîne de caractères sans aucune virgule
mais contenant au moins une fois le mot cœur.

Quand au test global, il vérifie qu'il y a bien une sous-chaîne de
type RE au début, puis qu'à chaque fois qu'on rencontre une virgule
celle-ci est suivi d'une autre sous-chaîne de type RE, et ce jusqu'à
la fin.


>> [...] ma
>> question d'origine qui est le contraire : vérifier qu'il existe au
>> moins l'une des parties de la phrase ne contenant *pas* ce mot.
>
> Pour cette version, la regexp suivante a l'air d'aller :
> /(^|,)([^,](?!cœur))*(,|$)/

Ici, le cœur (sic) de la regexp peut s'écrire :
/(^|,)([^,])*(,|$)/
voire, encore plus simplement :
/(^|,)[^,]*(,|$)/

Cette regexp consiste à considérer indépendamment chaque sous-chaîne
délimitée soit par des virgules, soit par le début ou la fin de la
chaîne.
- à gauche, le début de la chaîne ou une virgule : (^|,)
- à droite, une virgule ou la fin de la chaîne : (,|$)
- entre les deux, une séquence de caractères sans virgules : [^,]*

Mais en outre on veut vérifier que nulle part à l'intérieur de cette
sous-chaîne on ne rencontre le mot cœur. Ceci est réalisé par une
assertion à chaque non-virgule (à chaque [^,]) pour vérifier qu'à
cet endroit là ce n'est pas suivi par le mot cœur : (?!cœur).

Le test complet « il y a un caractère qui n'est pas une virgule et
qui n'est pas suivi par le mot cœur » est : ([^,](?!cœur))

Il n'y a plus qu'à le répéter n fois (multiplicateur *) et à
l'insérer entre le test de début et le test de fin de sous-chaîne.


Et voilà ! Encore merci à Otomatic, et à une prochaine fois pour de
nouvelles aventures regexpiennes.

--
Olivier Miakinen

Dominique

unread,
Jun 11, 2022, 12:35:26 AM6/11/22
to
Le 14/03/2022 à 10:47, Olivier Miakinen a écrit :

> Oui, ce serait une bonne idée si c'était possible. Mais dans mon cas
> précis il n'y a pas de moyen simple de modifier le code, seulement
> les regexp. Je ne peux pas non plus capturer des sous-chaînes pour
> les traiter séparément ensuite.

J'avais trouvé cette solution :

test="Pour parler à cœur ouvert, je mets une phrase vide, cœur à cœur,
je mets du cœur à l'ouvrage, même si ce n'est pas de gaieté de cœur."

test1=test.split(',')

test1
Out[22]:
['Pour parler à cœur ouvert',
' je mets une phrase vide',
' cœur à cœur',
" je mets du cœur à l'ouvrage",
" même si ce n'est pas de gaieté de cœur."]

'cœur' in test1[1]
Out[23]: False

'cœur' in test1[2]
Out[24]: True

Mais ça ne répond pas aux cahier des charges !

Bonne journée,

Dolminique

Olivier Miakinen

unread,
Jun 11, 2022, 4:48:02 AM6/11/22
to
Le 11/06/2022 06:35, Dominique a répondu à une question du 14/03 :
>
>> [...] Je ne peux pas non plus capturer des sous-chaînes pour
>> les traiter séparément ensuite.
>
> J'avais trouvé cette solution :
>
> [capturer des sous-chaînes par split() pour les traiter séparément ensuite]
>
> Mais ça ne répond pas aux cahier des charges !

En effet !

> Bonne journée,

Et bon trimestre. ;-)


--
Olivier Miakinen

Olivier Miakinen

unread,
Feb 28, 2023, 8:40:07 AM2/28/23
to
Le 28/02/2023 à 14:26, "Benoît L." a écrit :
> Nonobstant quelques doutes, le 11 juin 2022 à 09:48, Olivier Miakinen se
> permit de dire :

Oulà ! Le 11 juin 2022, ça fait longtemps que je n'ai plus le contexte,
d'autant que mon serveur de news n'a qu'une rétention d'un mois.
> Une question de béotien (Olivier validera mes dires) : Ne peut-on
> utiliser deux variables ? Une qui contient le nombre de phrases et une
> qui contient le nombre de phrases avec la string pour ensuite les
> comparer ou produire une string telle que : X phrases et Y occurrences,
> ou plus simplement X Y, X_Y…

Sans contexte j'ai du mal à valider ou infirmer quoi que ce soit.

Disons juste que s'il y a deux sous-chaînes extraites de la même chaîne,
alors oui, on peut les mettre dans deux variables, souvent $1 et $2 même
si ça dépend du langage utilisé faisant appel aux regexp. Cela peut être
aussi deux éléments d'un tableau résultat[1] et résultat[2].

> Une mauvaise idée bien sûr ;)

Je n'en sais rien. Si tu as un besoin particulier, alors tu vas devoir
expliquer exactement ce que tu as besoin de faire pour que je (ou que
quelqu'un d'autre) puisse te répondre.

Cordialement,
--
Olivier Miakinen

Olivier Miakinen

unread,
Feb 28, 2023, 1:06:27 PM2/28/23
to
Le 28/02/2023 à 15:33, "Benoît L." a écrit :
>
>> Je n'en sais rien. Si tu as un besoin particulier, alors tu vas devoir
>> expliquer exactement ce que tu as besoin de faire pour que je (ou que
>> quelqu'un d'autre) puisse te répondre.
>
> J’ai remonté l’enfilade depuis <t0lcik$1616$1...@cabale.usenet-fr.net> ;)

Ah oui, je m'en souviens maintenant, c'est moi qui avais eu ce besoin.
Je me rappelle que j'avais trouvé une solution, que j'avais sans doute
donnée. Si tu as le même besoin, puisque tu sais retrouver les articles
anciens tu devrais pouvoir le retrouver aussi.

Quoi qu'il en soit, pour ma part je n'en ai plus besoin.

--
Olivier Miakinen

Olivier Miakinen

unread,
Feb 28, 2023, 5:50:20 PM2/28/23
to
Le 28/02/2023 à 23:12, "Benoît L." a écrit :
>
> Je n’en ai pas besoin, mais j’ai trouvé le problème intéressant. D’où
> mon idée de solution.

Ah, ok.

Alors du coup, bien que je ne me rappelle pas quelle regexp j'ai
finalement utilisée, je peux au moins t'assurer d'une chose : c'est
que dans mon cas il était impossible d'utiliser des variables. Et
donc ton idée de solution avec deux variables ça ne pouvait pas
marcher, puisque même une seule variable était impossible.

Tout ce dont je disposais c'était :
- une regexp globale matche ;
- une regexp globale ne matche pas ;
- ou une combinaison par ET, OU et NON des deux premiers cas.

--
Olivier Miakinen

Olivier Miakinen

unread,
Feb 28, 2023, 5:59:09 PM2/28/23
to
Allez, pour ceux que cela intéresse, je recopie l'article en question.

Le 28/02/2023 à 15:33, "Benoît L." a écrit :
>
> J’ai remonté l’enfilade depuis <t0lcik$1616$1...@cabale.usenet-fr.net> ;)

§
Bonjour,



D'habitude c'est le plus souvent moi qui donne la solution à un problème

de regexp, mais pour une fois c'est moi qui ai besoin d'aide.



Dans une phrase comportant plusieurs mots séparés entre autres par des

virgules, je voudrais vérifier qu'un mot en particulier se trouve dans

chaque partie de la phrase.





Par exemple, pour le mot cœur, cette phrase serait valide :



Pour parler à cœur ouvert, cœur à cœur, je mets du cœur à l'ouvrage,

même si ce n'est pas de gaieté de cœur.





En revanche celle-ci ne serait pas valide :



Pour parler à cœur ouvert, cœur à cœur, je mets beaucoup de courage,

même si ce n'est pas de gaieté de cœur.



§

Olivier Miakinen

unread,
Feb 28, 2023, 6:04:21 PM2/28/23
to
[Supersedes]

Allez, pour ceux que cela intéresse, je recopie l'article en question.

Le 28/02/2023 à 15:33, "Benoît L." a écrit :
>
> J’ai remonté l’enfilade depuis <t0lcik$1616$1...@cabale.usenet-fr.net> ;)

§
Bonjour,

D'habitude c'est le plus souvent moi qui donne la solution à un problème
de regexp, mais pour une fois c'est moi qui ai besoin d'aide.

Dans une phrase comportant plusieurs mots séparés entre autres par des
virgules, je voudrais vérifier qu'un mot en particulier se trouve dans
chaque partie de la phrase.


Par exemple, pour le mot cœur, cette phrase serait valide :

Pour parler à cœur ouvert, cœur à cœur, je mets du cœur à l'ouvrage,
même si ce n'est pas de gaieté de cœur.


En revanche celle-ci ne serait pas valide :

Pour parler à cœur ouvert, cœur à cœur, je mets beaucoup de courage,
même si ce n'est pas de gaieté de cœur.

§

Olivier Miakinen

unread,
Feb 28, 2023, 6:15:19 PM2/28/23
to
Le 01/03/2023 à 00:04, Olivier Miakinen a écrit :
>
> Dans une phrase comportant plusieurs mots séparés entre autres par des
> virgules, je voudrais vérifier qu'un mot en particulier se trouve dans
> chaque partie de la phrase.

Et une solution possible (je ne sais pas si c'est celle que j'avais
retenue), c'est de faire l'inverse : une regexp qui réponde FAUX
si un mot en particulier se trouve dans chaque partie de la phrase,
c'est-à-dire qui réponde VRAI si ce mot est absent d'au moins une
des parties de la phrase.

La regexp suivante semble convenir :
(^|,)(.(?!cœur))*(,|$)
et c'est encore une démonstration de la puissance des assertions.

> Par exemple, pour le mot cœur, cette phrase serait valide :
>
> Pour parler à cœur ouvert, cœur à cœur, je mets du cœur à l'ouvrage,
> même si ce n'est pas de gaieté de cœur.

La regexp ne trouve rien ici.

> En revanche celle-ci ne serait pas valide :
>
> Pour parler à cœur ouvert, cœur à cœur, je mets beaucoup de courage,
> même si ce n'est pas de gaieté de cœur.

Ici, la regexp trouve ", je mets beaucoup de courage,"


Cordialement,
--
Olivier Miakinen
0 new messages