A quoi servent les parentheses autour des variables $un et $deux (bon, c'est sur qu'elles servent, parce que si je les mets pas ca me retourne 1) ?
($un)= $var =~ /(?<=carac2=)(.*?)\s/;
Les parenthèses de la regex nous permet de faire une capture dans les variables spéciales $1,$2, etc
donc je pourrais écrire
$var =~ /(?<=carac2=)(.*?)\s/;
$un = $1;
En revanche j'ai choisi ($un) à cause de ma paresse.
Pourquoi $un entouré des parenthèses?
Parce que je fais la capture de la regex dans un contexte de liste sans avoir besoin de passer par les variables $1, etc...
Ca c'est un point essentiel en Perl. Si tu ne comprends pas ça alors c'est difficile d'aller plus loin.
L'affectation d'une liste dans un contexte scalaire retourne le nombre d'éléments qui sont affectés. En ce cas un seul
Si tu fait plusieurs captures et tu utilises seulement une variable en contexte de liste alors les autres captures seront perdues.
Voici un exemple en utilisant le contexte de liste et le contexte scalaire
1. Lire une liste dans un contexte scalaire - retourne les nombres d'éléments
$ echo Perl pour plaisir | perl -ne '$nombre = ($un,$deux,$trois) = $_ =~ /(p)/gi;print "$nombre\n"'
$ echo Perl pour plaisir | perl -ne '$nombre = () = $_ =~ /(p)/gi;print "$nombre\n"'
3
$ echo Perl pour plaisir | perl -ne '$nombre = @nombre = $_ =~ /(p)/gi;print "$nombre\n"'
3
2. lire une liste dans un contexte de liste - retourne les éléments, avec la remarque que des valeurs sont perdu si on n'utilise pas le même nombre de variables - un solution c'est d'utiliser directement un tableau ou un hash (qui va bien dans ton cas vu que tu as des couple cle=valeur)
$ echo Perl pour plaisir | perl -ne '($un) = $_ =~ /(p)/gi;print "$un $deux $trois\n"'
P
$ echo Perl pour plaisir | perl -ne '($un,$deux) = $_ =~ /(p)/gi;print "$un $deux $trois\n"'
P p
$ echo Perl pour plaisir | perl -ne '($un,$deux,$trois) = $_ =~ /(p)/gi;print "$un $deux $trois\n"'
P p p
$ echo Perl pour plaisir | perl -ne '@nombre = $_ =~ /(p)/gi;print "@nombre\n"'
P p p
Et ensuite deuxième question, c'est ce que signifie les ?<= avant les carac1 et carac2,
Il s'agit d'un test arrière positif. Donc pour capturer ce que j'ai besoin, je regarde en arrière pour voir si le motif correspond.
C'est très pratique quand on parse des gros fichier, puisque le test avant et/ou arrière, positif et/ou negatif, ne consomment pas de texte, ce qui peut rendre une regex plus performante.
Pareil pour le ? dans (.*?)
Ici il s'agit de la gourmandise du quantificateur *
Pour comprendre je vais te donner un exemple
$ echo commentcamarche
commentcamarche
$ echo commentcamarche | perl -ne 'print $1,"\n" if /(c.*c)/'
commentcamarc
$ echo commentcamarche | perl -ne 'print $1,"\n" if /(c.*?c)/'
commentc
Dans le 1er cas .* tu remarques que * avale toute les caractères compris entre le 1er c et le dernier c de notre chaine.
En bref * veut dire : prendre zéro caractères, un caractères ou n'importe combien tu peux.
Comme * il est gourmand alors il va prendre tout
Dans le 2ème cas .*? la capture s'arrête au 1er c rencontré.
*? veut dire : prend zéro caractères, un caractère, mais content toi avec le minimum.
On peut tirer la conclusion qu'un quantificateur minimal préfère la satisfaction à la gourmandise
Une autre situation ça sera: la récupération de la chaine entre l'avant dernier et le dernier c
En ce cas on va écrire comme ça
$ echo commentcamarche | perl -ne 'print $1,"\n" if /.*(c.*c)/'
camarc
D'abord la regex va avaler tout grace à .* et ensuite il sera obliger de céder sous contrainte le 1er c rencontrer qui est le dernier dans la chaine.
Une fois que la regex a récupéré le dernier c va essayer d'avaler encore des caractères pour trouver un autre c, mais comme elle ne le trouve pas le .* de début va céder encore un caractère et ainsi de suite jusqu'à quand c.*c et satisfait
Bon, j'espère que tu as compris un peu :-))