OVH Cloud OVH Cloud

Extraire les composantes d'une expression régulière ?

22 réponses
Avatar
Picard
Bonjour,

je dois faire un développement en environnement Linux pour lequel je n'ai pas le
droit d'utiliser des COTS externes à l'environnement par défaut de Suse.
J'ai trouvé comme seul librairie, regexp, qui semble tout à fait correspondre à
ce que j'attends.

Je dois parser une chaîne de caractères dont le format est du genre:
<identifiant composé de caractères quelconques y compris _>_<valeur
entière>-<valeur entière>x<valeur entière>
Mon idée est de pouvoir extraire chaque entité défini entre <>.

Pour cela, j'ai écrit le code décrit ci-dessous.

Je me trouve confronté à différents problèmes:
- si j'utilise l__pattern tel que défini, cela ne matche pas un fichier de nom
"PF_toto_0-320x245.tutu.tata"
- si j'utilise l__pattern="([:alnum:_]+)-", cela matche: il m'affiche la chaîne
"PF_toto_0-" alors que j'attendais seulement "PF_toto_0".

Serait-il possible de m'expliquer pourquoi mon code ne fonctionne pas, s'il vous
plaît ?
Si l'explication est un peu longue, je suis prêt à accepter uniquement le bout
de code qui va bien ;-)

Ma contrainte est d'utiliser des expressions régulières car je souhaite en
comprendre le mécanisme. Je ne suis donc pas intéressé par une solution à base
de strtok.

Merci par avance pour votre aide.


#include "regex.h"

....

const char* l__pattern =
"([:alnum:_]+)_([:digit:]+)-([:digit:]+)x([:digit:]+)";
regex_t l__regex;
int l__rc = regcomp(&l__regex,l__pattern,REG_EXTENDED);
if (0 == l__rc)
{
int l__match;
size_t l__nmatch = 0;
regmatch_t *l__pmatch = NULL;
l__nmatch = l__regex.re_nsub;
cout << "nmatch = " << l__nmatch << endl;
l__pmatch = (regmatch_t *)malloc (sizeof (*l__pmatch) * l__nmatch);

l__match = regexec (&l__regex, l__file, l__nmatch, l__pmatch, 0);
regfree (&l__regex);
if (0==l__match)
{
cout << "filename " << l__file << " matches the file naming rule"
<< endl;
char *site = NULL;
int start = l__pmatch[0].rm_so;
int end = l__pmatch[0].rm_eo;
size_t size = end - start;
site = (char *)malloc (sizeof (*site) * (size + 1));
cout << "start="<<start<<" end="<<end << " size=" << size << endl;
memset(site,0,sizeof (*site) * (size + 1));
if (site)
{
strncpy (site, &l__file[start], size);
printf ("%s\n", site);
}
}
else
{
cout << "filename " << l__file << " does not match the file naming
rule" << endl;
}
}

10 réponses

1 2 3
Avatar
Jean-Marc Bourguet
"Picard" writes:

Mais cela, c'est par défait car je n'ai trouvé aucune librairie
traitant les expressions régulières en C++ mais sans COTS
supplémentaire genre Boost.


Boost a des expressions regulieres.

Avatar
loufoque

#include "regex.h"


Ceci est une bibliothèque C, comme le montre le merveilleux usage de
pointeurs et de malloc.
Il serait peut-être plus approprié d'utiliser une bibliothèque C++ ou
une bibliothèque C avec des wrappers C++.

De plus, il me semble que ton problème n'est lié qu'aux expressions
régulières et non pas à la programmation avec quel langage que ce soit.

Avatar
Picard
Difficile en effet de contester que mon code ressemble plus à du C
qu'à du C++.
Comme je fais des tests, j'ai simplement repompé le code exemple que
j'ai trouvé sur le net et qui est effectivement du C.

Mais cela, c'est par défait car je n'ai trouvé aucune librairie
traitant les expressions régulières en C++ mais sans COTS
supplémentaire genre Boost.
En particulier, je n'ai rien trouvé dans la librairie STL.
De même, je n'ai pas trouvé en C++ l'équivalent de la fonction C
glob.

Si vous avez connaissance de telles librairies, je suis intéressé
(même si j'ai réussi finalement à faire marcher ce code :je n'ai
donc plus besoin d'aide dessus).
Là, je pense que c'est une question de langage.

Mais je rappelle cette contrainte forte: je ne peux récupérer
d'autres librairies hors celles fournies par défaut avec Linux Suse
9.2 et ce, même si elles sont gratuites comme regex++.
Avatar
loufoque

Mais cela, c'est par défait car je n'ai trouvé aucune librairie
traitant les expressions régulières en C++ mais sans COTS
supplémentaire genre Boost.


Suse doit avoir un paquet pour installer boost.


En particulier, je n'ai rien trouvé dans la librairie STL.
De même, je n'ai pas trouvé en C++ l'équivalent de la fonction C
glob.


les expressions régulières sont dans TR1.

Avatar
Picard
Je viens de faire une recherche : la librairie TR1 est supportée à
partir de la version 10.0 de Suse.
Il semblerait que ce soit la première version de Suse supportant un
module offrant le support des expressions régulières en C++.

Je pense donc que je vais m'arrêter là dans mes recherches.

Je vous remercie beaucoup pour votre aide et pour le temps que vous
avez bien voulu consacrer à répondre à mes questions.
Avatar
kanze
Picard wrote:

Difficile en effet de contester que mon code ressemble plus à
du C qu'à du C++. Comme je fais des tests, j'ai simplement
repompé le code exemple que j'ai trouvé sur le net et qui est
effectivement du C.

Mais cela, c'est par défait car je n'ai trouvé aucune
librairie traitant les expressions régulières en C++ mais sans
COTS supplémentaire genre Boost.


D'abord, c'est quoi, COTS ? Et Boost est livré avec Mandriva --
c'est peut-être aussi le cas de Suse.

En particulier, je n'ai rien trouvé dans la librairie STL. De
même, je n'ai pas trouvé en C++ l'équivalent de la fonction C
glob.


Pour la simple raison qu'il n'existe pas. Ni en C ni en C++.

Si vous avez connaissance de telles librairies, je suis
intéressé (même si j'ai réussi finalement à faire marcher ce
code :je n'ai donc plus besoin d'aide dessus). Là, je pense
que c'est une question de langage.

Mais je rappelle cette contrainte forte: je ne peux récupérer
d'autres librairies hors celles fournies par défaut avec Linux
Suse 9.2 et ce, même si elles sont gratuites comme regex++.


Ça me semble une contrainte assez artificielle. D'une part, même
g++ ne fait pas partie du noyau -- c'est quelque chose de plus.
Et de l'autre, au moins certaines distributions de Linux inclut
Boost.

Ceci dit : ta fonction regex fait partie de Posix. C'est donc du
C, pure et simple. Mais c'est assez facile à le wrapper dans une
classe C++.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Avatar
Gabriel Dos Reis
"kanze" writes:

| Picard wrote:
|
| > Difficile en effet de contester que mon code ressemble plus à
| > du C qu'à du C++. Comme je fais des tests, j'ai simplement
| > repompé le code exemple que j'ai trouvé sur le net et qui est
| > effectivement du C.
|
| > Mais cela, c'est par défait car je n'ai trouvé aucune
| > librairie traitant les expressions régulières en C++ mais sans
| > COTS supplémentaire genre Boost.
|
| D'abord, c'est quoi, COTS ? Et Boost est livré avec Mandriva --
| c'est peut-être aussi le cas de Suse.

C'est le cas.

-- Gaby
Avatar
Picard
COTS = Component On The Shelf (Composant sur étagères en français).

Boost est livré avec Suse 10.0, pas avec Suse 9.2.

Pour être plus précis, je ne peux utiliser de composant logiciel non
offert via l'interface Yast.
g++ est proposé via l'interface Yast même s'il n'est pas installé
par défaut.
Boost n'est pas proposé par l'interface Yast : Il faut explicitement
installer Boost en récupérant la librairie sur le net.

Pour ce qui est de la fonction glob, elle existe puisque je l'utilise
avec succès (GNU C) et je n'ai installé que les composants logiciels
offerts par Yast sur Suse 9.2.

Tout à fait d'accord sur le dernier point.
Avatar
loufoque
Je viens de faire une recherche : la librairie TR1 est supportée à
partir de la version 10.0 de Suse.


TR1 est une extension à la bibliothèque standard de C++ qui sortira en
2009 normalement.
Je suis assez surpris, donc, que vous l'ayiez déjà.

Avatar
Picard
En fait, je ne l'ai pas encore puisque je n'ai pas encore Suse 10.0.

De mes investigations, j'ai cru comprendre que TR1 était un composant
fourni par Boost:
voir lien http://lists.boost.org/boost-announce/2005/09/0070.php

Il se trouve que lorsque je regarde le contenu de la librairie Suse
10.0 (cf
http://www.novell.com/products/linuxpackages/professional/boost-doc.html),
on y trouve la librairie regex.

Je me suis donc permis ce raccourci même si rien n'indique qu'il
s'agit de la librairie TR1.
Il peut toutefois s'agir d'une erreur de ma part.
Dans ce cas, ne pas hésiter à me le signaler. Après tout, on est là
pour apprendre.
1 2 3