Comment écrire une regex avec 2 mots [Résolu/Fermé]

Signaler
Messages postés
229
Date d'inscription
vendredi 31 juillet 2015
Statut
Membre
Dernière intervention
24 février 2017
-
Messages postés
229
Date d'inscription
vendredi 31 juillet 2015
Statut
Membre
Dernière intervention
24 février 2017
-
Bonjour,

Je souhaite rechercher les mots au pluriel, j'ai une regex qui n'est pas assez efficace. Je recherche tous les motifs qui se terminent par s ou x.
Maintenant, je souhaite changer cette regex en ajoutant une autre règle. Le motif sera le mot qui se termine par s ou x mais qui est précédé par un article tel que les, des, nos...
Je ne vois pas comment modifier la regex sachant que ce sera 2 mots.
Ma regex actuelle :
"[sx]$"

Merci

2 réponses

Messages postés
5432
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
15 octobre 2020
907
Salut geekat,

Et tu utilises quel moteur de regexp ?

Si tu utilises un moteur PCRE, tu peux faire
"(les|des|nos)\s[^\s].+[sx]$"
par exemple.

Note que comme tu as mis un $, ta regexp ne matchera que si le s ou x se trouve en fin de chaîne.


Dal
1
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 60511 internautes nous ont dit merci ce mois-ci

Messages postés
229
Date d'inscription
vendredi 31 juillet 2015
Statut
Membre
Dernière intervention
24 février 2017
>
Messages postés
5432
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
15 octobre 2020

Bonjour,
J'ai réglé le problème avec strtok, et je récupère à chaque fois 2 mots consécutifs que je concatène avec un espace.
J'ai essayé la regex au départ
"je\\sfinis"
, il me trouve bien ces mots car ils sont dans le texte. Par contre, j'ai essayé tes regex :
"(les|des|nos)\s[^\s]+[sx]$"
"(les|des|nos) [^ ]+[sx]$"
avec \\s et je n'arrive pas à avoir le motif. :(
Messages postés
5432
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
15 octobre 2020
907
ton message ci-dessus est très confus pour moi. De plus, "je\\sfinis" ne risque pas de matcher les regexps fournies, et ce n'est pas un pluriel.

peux tu :

- dire d'où vient ton moteur de regexp ?
- poster un code court avec un jeu de données d'exemple, qui illustre comment tu utilises la regexp, ce que tu veux obtenir, ce que tu obtiens à la place, et pourquoi tu penses que c'est un problème
- indiquer si tu veux juste savoir si la regexp matche, ou si tu veux aussi capturer le résultat matché


Dal
Messages postés
229
Date d'inscription
vendredi 31 juillet 2015
Statut
Membre
Dernière intervention
24 février 2017
>
Messages postés
5432
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
15 octobre 2020

Merci pour ta réponse.
J'ai essayé "je\\sfinis" juste pour savoir si l'espace marche bien.
J'ai essayé "les" tout seul il marche mais "(les|des)" ne marche pas, bien que j'ai ça dans mon texte.
Voici le code de la regexp :
int is_valid_pluriel(char* words2, char* pluriel, FILE* fichier_pluriel)
{
  int i;
  regex_t preg; 
      if (regcomp(&preg,"[ld]es\\s[a-z]",  REG_NOSUB) != 0) 
      
      { 
       return(-1);
       
   }
   i = regexec (&preg, words2, 0, NULL, 0);
   if(i==0)
    {
     printf("\n ****************motif trouve\n************");
     // afficher
     printf("\n%s ",words2);
                                        // sauvegarder
     char ch1[4]="\n";
     char *ch2 = words2;
           pluriel = strcat(ch1,ch2);
            fputs(pluriel,fichier_pluriel);
     
    }
    
   if (i == 1)
   { 
    printf("\n motif NON trouve \n");
   }
}

Ce jeu de données me donne :
"les patates" , "les framboises", "des gens" mais aussi "files de"
C'est juste un test, je remarque que les parenthèses ne marchent pas. Ce que je veux obtenir c'est le pluriel que j'ai dit au départ, ton code est bien mais il veut pas marcher chez moi.
Messages postés
229
Date d'inscription
vendredi 31 juillet 2015
Statut
Membre
Dernière intervention
24 février 2017
>
Messages postés
229
Date d'inscription
vendredi 31 juillet 2015
Statut
Membre
Dernière intervention
24 février 2017

Ah je crois que le problème vient de la syntaxe de regcomp, qui est incomplète :
 (regcomp(&preg,"(les|des|nos)\\s[^\\s]+[sx]$",  REG_NOSUB | EXTENDED) != 0)

Tout ça a l'air de marcher :)
Messages postés
229
Date d'inscription
vendredi 31 juillet 2015
Statut
Membre
Dernière intervention
24 février 2017
>
Messages postés
229
Date d'inscription
vendredi 31 juillet 2015
Statut
Membre
Dernière intervention
24 février 2017

Merci beaucoup pour ton aide. Il détecte bien le pluriel :)
Messages postés
5432
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
15 octobre 2020
907
Salut geekat,

On dirait que tu utilises les fonctions POSIX de regexp, si c'est le cas, on dirait que le modificateur est REG_EXTENDED (pas juste EXTENDED). Elles sont effectivement disponibles sur les systèmes POSIX en incluant l'entête <regex.h> (https://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap09.html).

Sous Linux, on a la doc de ces fonctions sous
man 3 regex
et les pages du standard POSIX donnent aussi des exemples.

Je n'avais jamais utilisé ce moteur de regexp en C (ou un autre en C), alors j'ai testé ceci sous Linux Debian, pour voir les possibilités :

#include <stdio.h>
#include <string.h>
#include <regex.h>

#define CHAR_SEPARATEURS " .;:,?!\n"

int main(void) {
    regex_t exp;
    regmatch_t m;
    char text[255]  = 
        "Les fleurs, des beaux jours...\n"
        "multicolores les champs\n"
        "les rires des enfants";
    char st[255];
    char * ptext;

    printf("testing with string:\n-----\n%s\n-----\n"
            "Haiku by [Dal] :-)\n\n", text);

    if (regcomp(
                &exp, 
                "(les|des|ses)(\\s[^\\s]+[sx])([" CHAR_SEPARATEURS "]|$)",
                REG_ICASE | REG_EXTENDED) != 0) {
        printf("Erreur regcomp()\n");
        return 0;
    }

    int r = regexec(&exp, text, 1, &m, 0);
    ptext = text;

    if (r == 0) {
        strncpy(st, ptext + m.rm_so, m.rm_eo - m.rm_so);
        st[m.rm_eo - m.rm_so] = '\0';
        printf("first captured: [%s]\n", st);
    }
    do {
        ptext = ptext + m.rm_eo;
        r = regexec (&exp, ptext, 1, &m, REG_NOTBOL);
        if (r == 0) {
            strncpy(st, ptext + m.rm_so, m.rm_eo - m.rm_so);
            st[m.rm_eo - m.rm_so] = '\0';
            printf("next captured: [%s]\n", st);
        }
    } while (r == 0);

    return 0;
}
donne :

$ gcc -Wall regexps.c
$ ./a.out
testing with string:
-----
Les fleurs, des beaux jours...
multicolores les champs
les rires des enfants
-----
Haiku by [Dal] :-)

first captured: [Les fleurs,]
next captured: [des beaux jours.]
next captured: [les champs
]
next captured: [les rires ]
next captured: [des enfants]
$

Cela permet rechercher la regexp sur une chaîne C composée éventuellement de plusieurs lignes et de matcher la fin de mot sur la fin de ligne, la fin de la chaîne ou sur un caractère séparateur, avec des majuscules ou pas.

C'est presque aussi plaisant à utiliser qu'avec Perl, mais n'exagérons rien, cela doit être le printemps ;-)


Dal
Messages postés
229
Date d'inscription
vendredi 31 juillet 2015
Statut
Membre
Dernière intervention
24 février 2017

Merci beaucoup pour toutes ces explications :)