Regex : trouver tous les mots de plus de 3 lettres entre deux autres mots

Résolu/Fermé
Soho_23 Messages postés 1 Date d'inscription vendredi 22 mars 2019 Statut Membre Dernière intervention 22 mars 2019 - 22 mars 2019 à 17:13
Whismeril Messages postés 18199 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 26 janvier 2023 - 6 mars 2020 à 09:10
Bonjour,

Je suis novice en Regex et je dois écrire (en java) une Regex pour trouver tous les mots de plus de 3 lettres entre deux mots données. .

Par exemple, je dois écrire une Regex qui trouve tous les mots de plus de 3 lettres qui se trouvent entre les mots "P(p)ig(s)" et "B(b)ird(s)" dans les phrases suivante :

Pigs are farm animals. Birds are not
My bird fly in his cage. My pig run in the garden.

Merci

5 réponses

Rostom2020 Messages postés 3 Date d'inscription mercredi 4 mars 2020 Statut Membre Dernière intervention 6 mars 2020
Modifié le 6 mars 2020 à 04:29
Bonjour,

Le but de ma réflexion n'était pas de remettre en question votre travail; au contraire vous étiez d'une grande aide pour moi et je vous remercie pour cela. Je voulais juste comprendre pourquoi le (?<=) ne marchait pas si j'enlevais" le ou"; si je laissais le (*.) ou si je rajoutais le "\\W*" pour la ponctuation par exemple "pigs;".

En tout les cas j'y travaille.
Merci beaucoup.
1
410Gone Messages postés 1 Date d'inscription vendredi 22 mars 2019 Statut Membre Dernière intervention 23 mars 2019
23 mars 2019 à 00:01
Salut,
Je te conseil d'utiliser ce site pour apprendre / tester tes regexs <a href="https://regex101.com">https://regex101.com</a>
pour la tienne on doit être sur quelque chose du style:
(bird|pig)(s){0,1}(.*)([a-z]{3,*})(.*)(bird|pig)(s){0,1} avec un flag en no case et le tour est joué
0
Whismeril Messages postés 18199 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 26 janvier 2023 886
23 mars 2019 à 06:35
Bonjour
Le conseil d’utiliser un site de test est très bon, et évite de poster une regex qui ne marche pas ;).

Celle-ci fonctionne
(?<=((birds?)|(pigs?)).*)\b[a-z]{3,}\b(?=.*((birds?)|(pigs?)))



0
Rostom2020 Messages postés 3 Date d'inscription mercredi 4 mars 2020 Statut Membre Dernière intervention 6 mars 2020
4 mars 2020 à 07:42
SVP, lorsque j'ai testé votre code sur Eclipse; il m'a déclencher une erreur: '
Look-behind group does not have an obvious maximum length', j'ai compris que le ?<= ne fonctionne pas avec (.*) il faut qu'il soit limité. Alors comment avez vous fait?
Merci.
0
Whismeril Messages postés 18199 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 26 janvier 2023 886
4 mars 2020 à 08:58
BONJOUR

Comme le montre la capture, je l’ai fair sur un site de test.
Copie colle le lien ci dessous
http://regexstorm.net/tester?p=%28%3f%3c%3d%28%28birds%3f%29%7c%28pigs%3f%29%29.*%29%5cb%5ba-z%5d%7b3%2c%7d%5cb%28%3f%3d.*%28%28birds%3f%29%7c%28pigs%3f%29%29%29&i=Pigs+are+farm+animals.+Birds+are+not+%0d%0aMy+bird+fly+in+his+cage.+My+pig+run+in+the+garden.&o=i


Mais effectivement sur un autre site (regex101.com) elle ne fonctionne pas.

Cela celle proposée par 410gone ne fonctionne pas non plus sur regex101.

0
Whismeril Messages postés 18199 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 26 janvier 2023 886 > Whismeril Messages postés 18199 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 26 janvier 2023
Modifié le 4 mars 2020 à 11:03
AU temps pour moi, quand je coche le langage JavaScript sur regex101, ma regex fonctionne aussi
https://regex101.com/r/piabvE/1
0
KX Messages postés 16664 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 21 janvier 2023 2 998
4 mars 2020 à 12:19
Pour que cela fonctionne en Java, il ne faut pas oublier de doubler les
\
et préciser que la regex doit être insensible à la casse (sinon la première ligne ne matchera pas).

Pattern pattern = Pattern.compile("(?<=((birds?)|(pigs?)).*)\\b[a-z]{3,}\\b(?=.*((birds?)|(pigs?)))",
    Pattern.CASE_INSENSITIVE);

String text = "Pigs are farm animals. Birds are not\n"
    + "My bird fly in his cage. My pig run in the garden.";

Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
    System.out.println(matcher.group(0));
}

Résultat :
are
farm
animals
fly
his
cage
0
Whismeril Messages postés 18199 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 26 janvier 2023 886 > KX Messages postés 16664 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 21 janvier 2023
4 mars 2020 à 13:30
Salut,

pour IgnoreCase ça avait été dit plus haut. Cependant, cela tolère biRd par exemple comme borne, si on ne veut que (B)bird et (P)ig
(?<=(([Bb]irds?)|([Pp]igs?)).*)\b[a-z]{3,}\b(?=.*(([Bb]irds?)|([Pp]igs?)))
0
Rostom2020 Messages postés 3 Date d'inscription mercredi 4 mars 2020 Statut Membre Dernière intervention 6 mars 2020
5 mars 2020 à 23:39
Bonjour,

Et merci pour vos réponses.
Effectivement si vous utilisez l'expression tel que vous avez décrit; cela fonctionne mais n'est pas totalement correcte puisqu'elle tolère des mots autres voulus; par exemple: birds are animals, also birds ------ le résultat va étre are animals et also; or c'est faux.
Et comme je voulez raffiner la recherche j'ai enlevé la partie qui vient après le ou, de (?<=(([Bb]irds?)|([Pp]igs?)).*) ce qui a engendré une erreur comme quoi le (?<=) ne tolère pas le *. et qu il faut que ça soit limitée.

Voila le pb que j ai eu.
Merci.
0
Whismeril Messages postés 18199 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 26 janvier 2023 886
5 mars 2020 à 23:50
e résultat va étre are animals et also; or c'est faux.

c'était pas précisé qu'il fallait que les bornes soient différentes.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Whismeril Messages postés 18199 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 26 janvier 2023 886
6 mars 2020 à 09:10
Quand tu
birds are animals, also birds ------ le résultat va étre are animals et also; or c'est faux.
pour moi c'est correct puisque animals et also sont des mots de plus de trois lettres compris entre et birds et birds.

Et comme je voulez raffiner la recherche j'ai enlevé la partie qui vient après le ou, de (?<=(([Bb]irds?)|([Pp]igs?)).*) ce qui a engendré une erreur comme quoi le (?<=) ne tolère pas le *. et qu il faut que ça soit limitée.


Les moteurs de regex sont un peu différents d'un langage à l'autre.
Par exemple, l'implémentation VBA ne permet pas de donner un nom à un groupe, ce qui est bien plus pratique que de compter les groupes pour savoir quel est l'index de celui que tu cherches.

Dans le cas présent, on a vu que sur Regex101 si on coche PHP, il y a une erreur, alors que sur Regexstorm qui utilise l'implémentation .Net ça fonctionne.
J'ai trouvé un site de test basé sur Java8 où il y a une erreur et un autre basé sur une version plus récente de Java où ça fonctionne.

J'ai essayé sur plein de sites, jusqu'à la réponse de KX, réponse que j'ai pensé résoudre le problème puisqu'il code en Java et a même posté le code complet.

Bref pendan mes différents tests j'ai eu 2 types d'erreurs, l'une disait que le "Zero-width positive lookbehind assertion" (que je traduirais par pré-requis) doit avoir une longueur fixe et l'autre erreur disait que le pré-requis doit avoir une longueur limitée.

Bref, on dirait qu'il y a 3 implémentations différentes pour les pré requis, la plus ancienne ne supportait qu'une longueur fixe, la seconde une longueur limitée et la plus récente peu importe.

Je pense donc cette erreur est due à ta version de Java (ou du moteur de regex) qui doit être ancienne.

Je voulais juste comprendre pourquoi le (?<=) ne marchait pas si j'enlevais" le ou"; si je laissais le (*.) ou si je rajoutais le "\\W*" pour la ponctuation par exemple "pigs;".

Sans les regex exactes que tu as essayé, je réponds dans le vide...
Pour le ou, si tu l'enlèves tu ne cherches plus qu'une seule borne donc tu ne captures plus entre pigs et birds par exemple.

0