Comment écrire une regex avec 2 mots
Résolu
geekat
Messages postés
223
Date d'inscription
Statut
Membre
Dernière intervention
-
geekat Messages postés 223 Date d'inscription Statut Membre Dernière intervention -
geekat Messages postés 223 Date d'inscription Statut Membre Dernière intervention -
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
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
-
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-
-
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 -
-
-
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
-
-
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 sousman 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