OVH Cloud OVH Cloud

probleme de regex

13 réponses
Avatar
GERBIER Eric
bonjour

je cherche a faire une regex qui correspond
- soit a des noms de fichiers ne contenant aucun espace : /tmp/toto
- soit a une chaine contenant eventuellement des espaces, mais entouree de
quotes : "un nom avec des espaces"

le code suivant marche :
#################################
sub test_file($) {
my $ligne = shift(@_);

if ($ligne =~ m/\"(.*)\"/) {
print "\!$ligne\! trouvé motif avec quotes : $1\n";
} elsif ($ligne =~ m/(\S+)/ ) {
print "\!$ligne\! trouvé motif : $1\n";
}
}

test_file('"un fichier"');
test_file('/un/autre');
#####################################

mais maintenant, j'aurais voulu tout regrouper dans un seul test , avec un |
############################################
sub test_file($) {
if ($ligne =~ m/\"(.*)\"|(\S+)/) {
print "test 2 \!$ligne\! trouvé motif : $1\n";
}
}
#########################################
mais ca ne marche pas :

test 2 !"un fichier"! trouvé motif : un fichier
Use of uninitialized value in concatenation (.) or string at ./essai.pl line 20.
test 2 !/un/autre! trouvé motif :

3 réponses

1 2
Avatar
Jack
Le 25/10/2004 19:01, :

À (at) Mon, 25 Oct 2004 17:31:15 +0200,
Jack écrivait (wrote):

Pour être factuel, Il me semblé que l'écriture proposée par Eric ne traitait
pas cela (comme il le souhaite).
ex:
titi" et grosminet" ""


Autre exemple:
"titi"estparti



Ces deux exemples ne me semblent pas valides (si j'ai bien compris la demande
initiale). Donc je ferais un truc du genre :

sub test_file { # pas de prototype (ce ne sert pas vraiment)
my ($ligne) = @_;
# on veut reconnaitre toute la ligne
# (d'où les ^ et les $ de debut et de fin)
if ($ligne =~ m/^"(.+)"$|^([^" ]+)$/) {
if (defined $1) {
print "fichier avec guillemets: $1n";
return $1;
} else {
print "fichier sans guillemets: $2n";
return $2;
}
} else {
die "Nom de fichier invalide: $ligne";
}
}

Mais peut-être n'ai-je rien compris à la demande initiale ! :-(



Comme la demande n'est explicite et qu'il n'y a pas de retour,
vous avez interprêté au mieux.

Si l'on retient la notion de fichier avec un path absolu:
/les animaux/titi
/les animaux/"gros minet"

semble plausibles?


Cette notations
} else {
die "Nom de fichier invalide: $ligne";
}

et celle-ci
print "Nom de fichier invalide: $lignen";
return;
}

peuvent elles considérer comme équivalentes en sortie?














Avatar
GERBIER Eric
Paul Gaborit wrote:

Ces deux exemples ne me semblent pas valides (si j'ai bien compris la demande
initiale). Donc je ferais un truc du genre :

sub test_file { # pas de prototype (ce ne sert pas vraiment)
my ($ligne) = @_;
# on veut reconnaitre toute la ligne
# (d'où les ^ et les $ de debut et de fin)
if ($ligne =~ m/^"(.+)"$|^([^" ]+)$/) {
if (defined $1) {
print "fichier avec guillemets: $1n";
return $1;
} else {
print "fichier sans guillemets: $2n";
return $2;
}
} else {
die "Nom de fichier invalide: $ligne";
}
}

Mais peut-être n'ai-je rien compris à la demande initiale ! :-(


désolé, je reponds avec beaucoup de retard (les vacances scolaires ...)
le code repond tout a fait a mon probleme !
comme ca, le code semble meme evident (pourquoi me suis-je efforcé d'utiliser S ?)

au passage j'ai aussi decouvert l'effet du pipe sur la correspondance des
arguments ($1 et $2)

j'en profite pour poser une question sur ce code : en terme de performance ou de
"style", vaut-il mieux ecrire un seul test avec une regex contenant ce pipe
ou utiliser un
if ($ligne =~ m/^"(.+)"$)/)
...
elsif ($ligne =~ m/^([^" ]+)$/)
...
else
...

merci encore pour cette aide

Avatar
Jack
Le 03/11/2004 14:59, :
Paul Gaborit wrote:


Ces deux exemples ne me semblent pas valides (si j'ai bien compris la d emande
initiale). Donc je ferais un truc du genre :

sub test_file { # pas de prototype (ce ne sert pas vraiment)
my ($ligne) = @_;
# on veut reconnaitre toute la ligne
# (d'où les ^ et les $ de debut et de fin)
if ($ligne =~ m/^"(.+)"$|^([^" ]+)$/) {
if (defined $1) {
print "fichier avec guillemets: $1n";
return $1;
} else {
print "fichier sans guillemets: $2n";
return $2;
}
} else {
die "Nom de fichier invalide: $ligne";
}
}

Mais peut-être n'ai-je rien compris à la demande initiale ! :-(



désolé, je reponds avec beaucoup de retard (les vacances scolaires ...)
le code repond tout a fait a mon probleme !
comme ca, le code semble meme evident (pourquoi me suis-je efforcé d' utiliser S ?)

au passage j'ai aussi decouvert l'effet du pipe sur la correspondance d es
arguments ($1 et $2)

j'en profite pour poser une question sur ce code : en terme de performa nce ou de
"style", vaut-il mieux ecrire un seul test avec une regex contenant ce pipe
ou utiliser un
if ($ligne =~ m/^"(.+)"$)/)
...
elsif ($ligne =~ m/^([^" ]+)$/)
....
else
....

merci encore pour cette aide


Ecrire une regex qui "consomme" le moins possible. ^ pourrait être
contourner.
ex: Si vous ne souhaitez que les noms conformes à votre règle
un test devrait suffir.
Avez vous besoin d'analyser le type de fichier reconnu conforme?

Une regex adaptée me semble puissant...


1 2