Comment écrire une regex avec 2 mots

Résolu/Fermé
geekat Messages postés 228 Date d'inscription vendredi 31 juillet 2015 Statut Membre Dernière intervention 24 février 2017 - Modifié par geekat le 8/06/2016 à 11:32
geekat Messages postés 228 Date d'inscription vendredi 31 juillet 2015 Statut Membre Dernière intervention 24 février 2017 - 19 juin 2016 à 13:28
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
A voir également:

2 réponses

[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 096
8 juin 2016 à 13:22
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
geekat Messages postés 228 Date d'inscription vendredi 31 juillet 2015 Statut Membre Dernière intervention 24 février 2017
8 juin 2016 à 13:33
Merci pour ta réponse.
J'ai suivi un tutoriel et je crois que c'est PCRE. Quoique je n'en suis pas sûre. J'utilise les fonctions de la bibliothèque regex.h .
J'ai essayé ta regex mais il ne me trouve rien.
0
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 096
Modifié par [Dal] le 8/06/2016 à 14:14
plus exactement, cela devrait être
"(les|des|nos)\s[^\s]+[sx]$"


Puisque tu sembles faire du C, je ne suis pas sûr si l'anti-slash "\s" ne doit pas être échappé en "\\s". Essaye éventuellement.

Sinon, si les mots sont séparés par des espaces, tu peux aussi faire
"(les|des|nos) [^ ]+[sx]$"
pour éviter les anti-slashs

Aurement, "regex.h" n'est pas une bibliothèque, c'est un entête, et cela ne renseigne pas sur la question.

Avec un moteur PCRE (pour Lisp et le moteur Perl lui même), j'ai pu vérifier que la regexp
"(les|des|nos)\s[^\s]+[sx]$"
matche sur des chaînes comme suit :

"les bateaux"
"des voiles"
"nos valeurs"

(sans les guillemets, avec du texte avant éventuellement, mais rien après puisque tu veux matcher des fins de lignes)

la regexp signifie :

- matche "les" ou "des" ou "nos"
- suivi d'un caractère blanc
- suivi d'au moins un caractère non blanc
- suivi(s) d'un caractère s ou x et de la fin de ligne

Dal
0
geekat Messages postés 228 Date d'inscription vendredi 31 juillet 2015 Statut Membre Dernière intervention 24 février 2017 > [Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024
8 juin 2016 à 14:51
Merci beaucoup!
Finalement, le problème vient du code que j'ai plus haut. La chaîne je la sépare déjà avec strtok pour séparer les mots. J'ai donc enlevé l'espace. J'ai besoin de cette fonction, mais du coup je ne sais plus comment sont séparés les mots.
0
geekat Messages postés 228 Date d'inscription vendredi 31 juillet 2015 Statut Membre Dernière intervention 24 février 2017
8 juin 2016 à 14:58
J'ai essayé ça :
char * words2 = strtok(chaine,"[]{}\\\n'{}()*/\"#.;:,\t'?!-<>&%+=");	  
is_valid_pluriel(words2,pluriel,fichier_pluriel);

Dans regex, j'ai essayé les 2 syntaxes : \s et \\s et c'est
\\s
qui marche.
ça marche! mais j'ai une chaîne comme résultat.
0
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 096
Modifié par [Dal] le 8/06/2016 à 16:52
avec l'information que tu donnes, je ne peux pas t'aider plus.

je t'ai donné une regexp PCRE qui matche ce que tu demandais.

strtok n'utilise pas de regexp en encore moins des PCRE, les tokens énumérés sont de simples char. Ton code ci-dessus ne démontre pas l'usage de strtok, qui passe de token en token par des appels successifs (sauf si tu fais cela ailleurs, par exemple dans la fonction appelée). Attention strtok est destructif et va altérer "chaine".

Bien sûr, si tu utilises strtok avec un espace en tant que token, tu ne vas pas pouvoir utiliser la puissance des PCRE sur plusieurs mots.

A toi de voir :-)

Dal
0
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 096
Modifié par [Dal] le 9/06/2016 à 13:47
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
0
geekat Messages postés 228 Date d'inscription vendredi 31 juillet 2015 Statut Membre Dernière intervention 24 février 2017
19 juin 2016 à 13:28
Merci beaucoup pour toutes ces explications :)
0