OVH Cloud OVH Cloud

Expression régulière (encore désolé ...)

12 réponses
Avatar
Francois
Salut à tous,

Je récupère ce type de ligne dans des fichiers :

<FROM>toto@test.com</FROM>
<TO>test@test.com</TO>
etc...

Je voudrai à l'aide d'expressions regulières récuperer dans une variable le
contenu entre 2 tags.

Comment feriez-vous pour le FROM par exemple ?

Merci d'avance.

--
Francois.

10 réponses

1 2
Avatar
Stephane Zuckerman
<FROM></FROM>
<TO></TO>


Si tu dois savoir de quelle balise provient ton texte, c'est très simple :

my $line = <STREAM>;
my $from;

# on prend tous les caractères entre les balises from (case insensitive)
($from = $line) =~ s:<from>(.*)</from>:$1:i;

Sinon, quelque chose du genre :

# non testé
my $result;
foreach my $line (<STREAM>) {
foreach my $tag (qw/from to etc/) {
if ($line =~ m:<$tag>(.*)</$tag>:i) {
$result = $1;
last;
}
}
# Le reste du boulot ici...
}

--
"Je deteste les ordinateurs : ils font toujours ce que je dis, jamais ce
que je veux !"
"The obvious mathematical breakthrough would be development of an easy
way to factor large prime numbers." (Bill Gates, The Road Ahead)

Avatar
Francois
"Stephane Zuckerman" a écrit dans le message de news:


Merci bcp pour ces pistes !

Quelques questions pour comprendre...

# on prend tous les caractères entre les balises from (case insensitive)
($from = $line) =~ s:<from>(.*)</from>:$1:i;


Quel est le sens de ($from = $line) ?

Je ne connais pas cette notation avec des ":" , est-ce équivalent à "/" ?

Merci encore.

--
Francois.

Avatar
Alex Marandon
On 2005-05-18, Francois wrote:
# on prend tous les caractères entre les balises from (case insensitive)
($from = $line) =~ s:<from>(.*)</from>:$1:i;


Quel est le sens de ($from = $line) ?


Les parenthèses donnent la priorité à cette expression. Donc la valeur
de $line est d'abord affectée à $from, ensuite la substitution est
effectuée sur $from.

Je ne connais pas cette notation avec des ":" , est-ce équivalent à "/" ?


Oui, je crois bien qu'on peut mettre n'importe quel caractère non
alphanumérique.


Avatar
Stephane Zuckerman
# on prend tous les caractères entre les balises from (case insensitive)
($from = $line) =~ s:<from>(.*)</from>:$1:i;


Quel est le sens de ($from = $line) ?


Les parenthèses donnent la priorité à cette expression. Donc la valeur
de $line est d'abord affectée à $from, ensuite la substitution est
effectuée sur $from.
Exactement. :-)


Je ne connais pas cette notation avec des ":" , est-ce équivalent à "/" ?


Oui, je crois bien qu'on peut mettre n'importe quel caractère non
alphanumérique.


Oui. En fait, étant donné qu'il y avait déjà un '/' dans la regexp, j'ai
préféré changer les caractères de séparation pour ne pas gêner la lecture
... Au début ça fait bizarre, mais ensuite je trouve qu'effectivement,
c'est plus lisible que d'avoir des '/' systématiques.

--
"Je deteste les ordinateurs : ils font toujours ce que je dis, jamais ce
que je veux !"
"The obvious mathematical breakthrough would be development of an easy
way to factor large prime numbers." (Bill Gates, The Road Ahead)



Avatar
Paul Gaborit
À (at) 18 May 2005 08:58:51 GMT,
Alex Marandon écrivait (wrote):
On 2005-05-18, Francois wrote:
Je ne connais pas cette notation avec des ":" , est-ce équivalent à "/" ?


Oui, je crois bien qu'on peut mettre n'importe quel caractère non
alphanumérique.


On peut choisir le délimiteur comme on veut... Il faut tout de même distinguer
deux cas : les délimiteurs qui marchent par paires (comme (), <>, {}, []) et
les autres (tous les symboles comme %, ^, &, !, :, etc.).

On peut donc écrire :

s/abc/cde/g;
s!abc!cde!g;
s:abc:cde:g;
s#abc#cde#g; # déconseillé pour une bonne coloration
etc.

Ou (avec les délimiteurs "pairés") :

s{abc}{cde}g;
s(abc)(cde)g;
etc.

Dans ces derniers cas, on peut même utiliser les caractères délimiteurs à
l'intérieur sans backslash s'ils sont bien imbriqués. Ex :

s{a{b}c}{c{d}e}g;

Pour plus d'info lire 'perlop'. En français :

<http://perl.enstimac.fr/DocFr/perlop.html>

et en particulier la section "Gory details of parsing quoted constructs" ou
(en français) "Les détails sordides de l'interprétation des chaînes" :

<http://perl.enstimac.fr/DocFr/perlop.html#les%20d%E9tails%20sordides%20de%20l'interpr%E9tation%20des%20cha%EEnes>

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>


Avatar
Francois
"Stephane Zuckerman" a écrit dans le message de news:


Oui. En fait, étant donné qu'il y avait déjà un '/' dans la regexp, j'ai
préféré changer les caractères de séparation pour ne pas gêner la lecture
... Au début ça fait bizarre, mais ensuite je trouve qu'effectivement,
c'est plus lisible que d'avoir des '/' systématiques.


Merci pour l'astuce, c'est effectivement bien plus lisible !

--
Francois.

Avatar
Nicolas George
Stephane Zuckerman wrote in message
:
# on prend tous les caractères entre les balises from (case insensitive)
($from = $line) =~ s:<from>(.*)</from>:$1:i;


Ça ne marche pas très bien. En fait, ça se contente de supprimer <from> et
</from>, et ça laisse ce qu'il y a en dehors.

my ($from) = $line =~ m:<from>(.*?)</from>:i;

serait largement préférable à mon avis.

Mais en fait, un parseur XML serait probablement préférable.

Avatar
Stephane Zuckerman
# on prend tous les caractères entre les balises from (case insensitive)
($from = $line) =~ s:<from>(.*)</from>:$1:i;


Ça ne marche pas très bien. En fait, ça se contente de supprimer <from> et
</from>, et ça laisse ce qu'il y a en dehors.


Oui, j'ai cru comprendre que c'était exactement ce qu'on voulait (donc en
gros j'ai supposé que la ligne courante ne comprend qu'un couple de
balises à la fois).

my ($from) = $line =~ m:<from>(.*?)</from>:i;

serait largement préférable à mon avis.


Je ne suis pas certain de comprendre ce que fait cette ligne (je décompose
tout le temps mes regexps à l'exception de la construction précédente).

Mais en fait, un parseur XML serait probablement préférable.
J'ai aussi pensé cela, mais je me suis dit que l'OP savait ce qu'il

demandait. :-)

--
"Je deteste les ordinateurs : ils font toujours ce que je dis, jamais ce
que je veux !"
"The obvious mathematical breakthrough would be development of an easy
way to factor large prime numbers." (Bill Gates, The Road Ahead)


Avatar
Francois
"Stephane Zuckerman" a écrit dans le message de news:


Mais en fait, un parseur XML serait probablement préférable.
J'ai aussi pensé cela, mais je me suis dit que l'OP savait ce qu'il

demandait. :-)


C'est tout à fait ce que je voulais, le but était justement d'abandonner un
parser XML qui donne plutôt l'impression d'une usine à gaz alors que les
regexp conviennent très bien à ces "petits" traitements.

Merci encore de m'avoir mis sur la voie, maintenant tout roule !

--
Francois.


Avatar
Nicolas George
Stephane Zuckerman wrote in message
:
my ($from) = $line =~ m:<from>(.*?)</from>:i;


Je ne suis pas certain de comprendre ce que fait cette ligne


L'opérateur m (match, qui est aussi l'opérateur qu'on a quand on n'écrit
rien) se contente de comparer $line avec l'expression régulière. Appelé en
contexte de liste, cet opérateur renvoit la liste de toutes les
sous-expressions capturées, donc ici le « .*? » (*?, c'est comme * sauf que
ça prend la sous-chaîne la plus courte possible).


1 2