NOM |
\w
reconnaisse les caractères nationaux ?/[a-zA-Z]/
?/o
?\b
ne marchent pas pour moi ?\G
dans une expression rationnelle ?
perlfaq6 - Expressions rationnelles ($Revision: 1.27 $, $Date: 1999/05/23 16:08:30 $)
Cette section est incroyablement courte car les autres sont parsemées de réponses concernant des expressions régulières. Par exemple, décoder une URL et vérifier si quelque chose est un nombre ou non est du domaine des expressions régulières, mais ces réponses existent ailleurs dans la FAQ (dans le chapitre sur les Données et le Réseau pour l'exemple donné).
Trois méthodes peuvent rendre les expressions régulières faciles à maintenir et compréhensibles.
# transforme la ligne en le premier mot, le signe deux points # et le nombre de caractères du reste de la ligne s/^(\w+)(.*)/ lc($1) . ":" . length($2) /meg;
/x
, les espaces seront ignorés dans le
motif de l'expression rationnelle (excepté dans un regroupement de
caractères), et vous pourrez aussi utiliser les commentaires habituels
dedans. Comme vous pouvez l'imaginer, espaces et commentaires aident
pas mal.
/x
vous permet de transformer ceci:
s{<(?:[^>'"]*|".*?"|'.*?')+>}{}gs;
en:
s{ < # signe inférieur (?: # parenthèse ouvrante ne faisant pas de référence [^>'"] * # 0 ou plus de caract. qui ne sont ni >, ni ' ni " | # ou ".*?" # une partie entre guillemets (reconnaissance min) | # ou '.*?' # une partie entre apostrophes (reconnaissance min) ) + # tout cela se produisant une ou plusieurs fois > # signe supérieur }{}gsx; # remplacé par rien, cad supprimé
Ce n'est pas encore aussi clair que de la prose, mais c'est très utile pour décrire le sens de chaque partie du motif.
/
, ils peuvent être délimités par presque n'importe
quel caractère. the perlre manpage l'explique. Par exemple, s///
ci-dessus
utilise des accolades comme délimiteurs. Sélectionner un autre
délimiteur permet d'éviter de le quoter à l'intérieur du motif :
s/\/usr\/local/\/usr\/share/g; # mauvais choix de délimiteur s#/usr/local#/usr/share#g; # meilleur
Ou vous n'avez pas plus d'une ligne dans la chaîne où vous faites la recherche (cas le plus probable), ou vous n'appliquez pas le bon modificateur à votre motif (cas possible).
Il y a plusieurs manières d'avoir plusieurs lignes dans une chaîne. Si
vous voulez l'avoir automatiquement en lisant l'entrée, vous
initialiserez $/ (probablement à ``'' pour des paragraphes ou undef
pour le fichier entier) ce qui vous permettra de lire plus d'une ligne
à la fois.
Lire the perlre manpage vous aidera à décider lequel de /s
et /m
(ou les
deux) vous aimeriez utiliser : /s
permet au point de reconnaître le
caractère fin de ligne, et /m
permet au circonflexe et dollar de
reconnaître tous les débuts et fins de ligne, pas seulement le début
et la fin de la chaîne. Vous pouvez l'utiliser pour être sûr que vous
avez bien plusieurs lignes dans votre chaine.
Par exemple, ce programme détecte les mots répétés, même s'ils sont
coupés (mais pas dans plusieurs paragraphes). Pour cet exemple, nous
n'avons pas besoin de /s
car nous n'utilisons pas le point dans
l'expression régulière dont on veut qu'elle enjambe les lignes. Nous
n'avons pas besoin non plus de /m
car nous ne voulons pas que le
circonflexe ou le dollar fasse une reconnaissance d'un début ou d'une
fin d'une nouvelle ligne. Mais il est impératif que $/ soit mis pour
autre chose que l'option par défaut, ou autrement nous n'aurons pas
plusieurs lignes d'un coup à se mettre sous la dent.
$/ = ''; # lis au moins un paragraphe entier, # pas qu'une seule ligne while ( <> ) { while ( /\b([\w'-]+)(\s+\1)+\b/gi ) { # les mots commencent par # des caractères alphanumériques print "$1 est répété dans le paragraphe $.\n"; } }
Voilà le code qui trouve les phrases commençant avec ``From '' (qui devrait être transformés par la plupart des logiciels de courrier électronique) :
$/ = ''; # lis au moins un paragraphe entier, pas qu'une seule ligne while ( <> ) { while ( /^From /gm ) { # /m fait que ^ reconnaisse # tous les débuts de ligne print "from de départ dans le paragraphe $.\n"; } }
Voilà le code qui trouve tout ce qu'il y a entre START et END dans un paragraphe :
undef $/; # lis le fichier entier, pas seulement qu'une ligne # ou un paragraphe while ( <> ) { while ( /START(.*?)END/sm ) { # /s fait que . enjambe les lignes print "$1\n"; } }
Vous pouvez utiliser l'opérateur quelque peu exotique ..
de Perl
(documenté dans the perlop manpage):
perl -ne 'print if /START/ .. /END/' fichier1 fichier2 ...
Si vous voulez du texte et non des lignes, vous pouvez utiliser
perl -0777 -ne 'print "$1\n" while /START(.*?)END/gs' fichier1 fichier2 ...
Mais si vous voulez des occurrences imbriquées de START
à
l'intérieur de END
, vous tombez sur le problème décrit, dans cette
section, sur la reconnaissance de texte bien équilibré.
Ici un autre exemple d'utilisation de ..
:
while (<>) { $in_header = 1 .. /^$/; $in_body = /^$/ .. eof(); # maintenant choisissez entre eux } continue { reset if eof(); # fixe $. }
$/ doit être une chaine, et non une expression rationnelle. Awk est au moins meilleur pour quelque chose. :-)
En fait, vous pouvez faire ceci si vous n'avez pas à vous soucier de mettre le fichier entier en mémoire :
undef $/; @records = split /your_pattern/, <FH>;
Le module Net::Telnet (disponible chez CPAN) a la capacité d'attendre pour un motif dans le flux d'entrée, ou fait un timeout si ce motif n'apparait pas dans un temps donné.
## Crée un fichier de trois lignes. open FH, ">file"; print FH "La première ligne\nLa deuxième ligne\nLa troisième ligne\n"; close FH;
## Lui met un handle de fichier en lecture/écriture. $fh = new FileHandle "+<file";
## L'attache à un objet "stream". use Net::Telnet; $file = new Net::Telnet (-fhopen => $fh);
## Cherche la deuxième ligne et imprime la troisième. $file->waitfor('/deuxième ligne\n/'); print $file->getline;
Voici une adorable solution perlienne par Larry Rosler. Elle exploite les propriétés du xor bit à bit sur les chaînes ASCII.
$_= "this is a TEsT case";
$old = 'test'; $new = 'success';
s{(\Q$old\E} { uc $new | (uc $1 ^ $1) . (uc(substr $1, -1) ^ substr $1, -1) x (length($new) - length $1) }egi;
print;
Et la voici sous la forme d'un sous-programme, selon le modèle ci-dessus :
sub preserve_case($$) { my ($old, $new) = @_; my $mask = uc $old ^ $old;
uc $new | $mask . substr($mask, -1) x (length($new) - length($old)) }
$a = "this is a TEsT case"; $a =~ s/(test)/preserve_case($1, "success")/egi; print "$a\n";
Ceci affiche :
this is a SUcCESS case
Rien que pour montrer que les programmeurs C peuvent écrire du C dans tous les langages de programmation, si vous préférez une solution plus proche du style de C, le script suivant fait en sorte que la substitution a la même casse, lettre par lettre, que l'original (il s'avère aussi tourner environ 240 % plus lentement que la version perlienne). Si la substitution a plus de caractères que la chaîne substituée, la casse du dernier caractère est utilisée pour le reste de la substitution.
# L'original est de Nathan Torkington, mis en forme par Jeffrey Friedl # sub preserve_case($$) { my ($old, $new) = @_; my ($state) = 0; # 0 = no change; 1 = lc; 2 = uc my ($i, $oldlen, $newlen, $c) = (0, length($old), length($new)); my ($len) = $oldlen < $newlen ? $oldlen : $newlen;
for ($i = 0; $i < $len; $i++) { if ($c = substr($old, $i, 1), $c =~ /[\W\d_]/) { $state = 0; } elsif (lc $c eq $c) { substr($new, $i, 1) = lc(substr($new, $i, 1)); $state = 1; } else { substr($new, $i, 1) = uc(substr($new, $i, 1)); $state = 2; } } # on se retrouve avec ce qui reste de new # (quand new est plus grand que old) if ($newlen > $oldlen) { if ($state == 1) { substr($new, $oldlen) = lc(substr($new, $oldlen)); } elsif ($state == 2) { substr($new, $oldlen) = uc(substr($new, $oldlen)); } } return $new; }
\w
reconnaisse les caractères nationaux ?Regardez the perllocale manpage.
/[a-zA-Z]/
?Un caractère alphabétique doit être /[^\W\d_]/
, quelle que soit la
locale que vous utilisez. Les non-alphabétiques doivent être
/[\W\d_]/
(sous réserve que vous ne considérez pas un souligné
comme une lettre).
L'analyseur syntaxique de Perl remplacera par leur valeur les
occurences de $variable et @variable dans les expressions régulières à
moins que le délimiteur ne soit une apostrophe. Rappelez-vous aussi que
la partie droite d'une s///
substitution est considérée comme une
chaîne entre guillemets (voir the perlop manpage pour plus de
détails). Rappelez-vous encore que n'importe quel caractère spécial
d'expression rationnelle agira à moins que vous ne précédiez la
substitution avec \Q. Voici un exemple :
$string = "to die?"; $lhs = "die?"; $rhs = "sleep, no more";
$string =~ s/\Q$lhs/$rhs/; # $string est maintenant "to sleep no more"
Sans le \Q, l'expression rationnelle aurait faussement aussi reconnu ``di''.
/o
?Utiliser une variable dans une opération de reconnaissance avec
expression régulière force une réévaluation (et peut-être une
recompilation) à chaque fois qu'elle est appliquée. Le modificateur
/o
verrouille l'expression régulière la première fois qu'elle est
utilisée. C'est toujours ce qui se passe avec une expression
rationnelle constante, et en fait, le motif est compilé dans le format
interne en même temps que le programme entier l'est.
Utiliser /o
est peu pertinent à moins que le remplacement de
variable ne soit utilisé dans le motif, et si cela est, le moteur
d'expression régulière ne prendra pas en compte les modifications de
la variable ultérieures à la toute première évaluation.
/o
est souvent utilisé pour gagner en efficacité en ne faisant pas
les évaluations nécessaires quand vous savez que cela ne pose pas de
problème (car vous savez que les variables ne changeront pas), ou plus
rarement, quand vous ne voulez pas que l'expression rationnelle
remarque qu'elles changent.
Par exemple, voici un programme ``paragrep'' :
$/ = ''; # mode paragraphe $pat = shift; while (<>) { print if /$pat/o; }
Bien que cela puisse se faire, c'est plus compliqué que vous ne pensez. Par exemple, cette simple ligne
perl -0777 -pe 's{/\*.*?\*/}{}gs' foo.c
marchera dans beaucoup de cas mais pas tous. Vous voyez, c'est un peu simplet pour certains types de programmes C, en particulier, ceux où des chaines protégées sont des commentaires. Pour cela, vous avez besoin de quelque chose de ce genre, créé par Jeffrey Friedl, modifié ultérieurement par Fred Curtis :
$/ = undef; $_ = <>; s#/\*[^*]*\*+([^/*][^*]*\*+)*/|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^/"'\\]*)#$2#gs; print;
Cela pourrait, évidemment, être écrit plus lisiblement avec le
modificateur /x
en ajoutant des espaces et des commentaires. Le
voici étendu, une courtoisie de Fred Curtis.
s{ /\* ## Début d'un commentaire /* ... */ [^*]*\*+ ## Non-* suivie par 1 ou plusieurs * ( [^/*][^*]*\*+ )* ## 0 ou plusieurs choses ne commençant pas par / ## mais finissent par '*' / ## Fin d'un commentaire /* ... */
| ## OU diverses choses qui ne sont pas des commentaires
( " ## Début d'une chaîne " ... " ( \\. ## Caractère échappé | ## OU [^"\\] ## Non "\ )* " ## Fin d'une chaîne " ... "
| ## OU
' ## Début d'une chaîne ' ... ' ( \\. ## Caractère échappé | ## OU [^'\\] ## Non '\ )* ' ## Fin d'une chaîne ' ... '
| ## OU
. ## Tout autre caractère [^/"'\\]* ## Caractères ne débutant pas un commentaire, ## une chaîne ou un échappement ) }{$2}gxs;
Une légère modification retire aussi les commentaires C++ :
s#/\*[^*]*\*+([^/*][^*]*\*+)*/|//[^\n]*|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^/"'\\]*)#$2#gs;
Quoique les expressions régulières de Perl soient plus puissantes que
les expressions régulières ``mathématiques'', car elles présentent des
avantages comme les motifs mémorisés (\1
et ses potes), elles ne
sont pas encore assez puissantes -- à la possible exception de
caractéristiques bizarres et expérimentales dans les versions de
développement de Perl. Vous avez encore besoin d'utiliser des
techniques autres pour analyser du texte bien équilibré, comme du
texte enclos par des parenthèses ou des accolades.
Une sous-routine élaborée (pour du 7-bit ASCII seulement) pour
extraire de simples caractères se correspondant et peut-être
imbriqués, comme `
et '
, {
et }
, ou (
et )
peut être
trouvée à
http://www.perl.com/CPAN/authors/id/TOMC/scripts/pull_quotes.gz .
Le module C::Scan module du CPAN contient de telles sous routines pour des usages internes, mais elles ne sont pas documentées.
La plupart des gens pensent que les expressions régulières gourmandes
reconnaissent autant qu'elles peuvent. Techniquement parlant, c'est en
réalité les quantificateurs (?
, *
, +
, {}
) qui sont
gourmands plutôt que le motif entier ; Perl préfère les gourmandises
locales et les gratifications immédiates à une gloutonnerie
globale. Pour avoir les versions non gourmandes des mêmes
quantificateurs, utilisez (??
, *?
, +?
, {}?
).
Un exemple:
$s1 = $s2 = "J'ai très très froid"; $s1 =~ s/tr.*s //; # J'ai froid $s2 =~ s/tr.*?s //; # J'ai très froid
Notez que la seconde substitution arrête la reconnaissance dès qu'un
``s '' est rencontré. Le quantificateur *?
dit effectivement au
moteur des expressions régulières de trouver une reconnaissance aussi
vite que possible et de passer le contrôle à la suite, comme de se
refiler une patate chaude.
Utilisez la fonction split :
while (<>) { foreach $word ( split ) { # faire quelque chose avec $word ici } }
Notez que ce ne sont pas vraiment des mots dans le sens français ; ce sont juste des suites de caractères différents de l'espace.
Pour travailler avec seulement des séquences alphanumériques, vous pourriez envisager
while (<>) { foreach $word (m/(\w+)/g) { # faire quelque chose avec $word ici } }
Pour faire cela, vous avez à sortir chaque mot du flux d'entrée. Nous appelerons mot une suite de caractères alphabétiques, de tirets et d'apostrophes plutôt qu'une suite de tout caractère sauf espace comme vue dans la question précédente :
while (<>) { while ( /(\b[^\W_\d][\w'-]+\b)/g ) { # on rate "`mouton'" $seen{$1}++; } } while ( ($word, $count) = each %seen ) { print "$count $word\n"; }
Si vous voulez faire la même chose avec les lignes, vous n'avez pas besoin d'une expression rationnelle :
while (<>) { $seen{$_}++; } while ( ($line, $count) = each %seen ) { print "$count $line"; }
Si vous voulez que le résultat soit trié, regardez la section sur les hachages.
Regardez le module String::Approx du CPAN.
Le code suivant est extrêmement inefficace :
# manière lente mais évidente @popstates = qw(CO ON MI WI MN); while (defined($line = <>)) { for $state (@popstates) { if ($line =~ /\b$state\b/i) { print $line; last; } } }
C'est parce que Perl doit recompiler tous ces motifs pour chacune des
lignes du fichier. À partir des versions 5.005, il existe une bien
meilleure approche, utilisant le nouvel opérateur qr//
:
# utilise le magnifique et tout neuf opérateur qr//, avec même le # drapeau /i use 5.005; @popstates = qw(CO ON MI WI MN); @poppats = map { qr/\b$_\b/i } @popstates; while (defined($line = <>)) { for $patobj (@poppats) { print $line if $line =~ /$patobj/; } }
\b
ne marchent pas pour moi ?Deux idées fausses communes sont que \b
est synonyme de \s+
, et
que c'est la frontière entre les espaces et les autres
caractères. Aucune n'est correcte. \b
est l'endroit entre un
caractère \w
et un \W
(c'est cela, \b
est la frontière d'un
``mot''). C'est une assertion de longueur nulle comme ^
, $
, et
tous les autres anchors, d'où il ne consomme aucun caractère.
the perlre manpage décrit le comportement de tous ces metacaractères.
Voici des exemples d'utilisation incorrecte de \b
, avec les
corrections :
"deux mots" =~ /(\w+)\b(\w+)/; # MAUVAIS "deux mots" =~ /(\w+)\s+(\w+)/; # bon
" =matchless= text" =~ /\b=(\w+)=\b/; # MAUVAIS " =matchless= text" =~ /=(\w+)=/; # bon
Quoiqu'ils peuvent ne pas faire ce que vous pensez qu'ils font, \b
et \B
peuvent être bien utiles. Pour un exemple d'utilisation
correcte de \b
, regardez l'exemple de reconnaissance de mots
dupliqués sur plusieurs lignes.
Un exemple d'utilisation de \B
est le motif \Best\B
. Il trouvera
les occurrences de ``est'' seulement à l'intérieur des mots, comme
``geste'', mais pas ``test'' ou ``estime''.
Parce qu'une fois que Perl voit que vous avez besoin d'une de ces variables quelque part, il doit les fournir pour chaque reconnaissance de motif. Le même mécanisme qui les prend en compte est fourni pour l'utilisation de $1, $2, etc... donc vous payez le même prix pour chaque expression rationnelle qui contient des parenthèses de capture. Mais si vous n'utilisez jamais $&, etc... dans votre script, alors les expressions régulières sans capture de parenthèses ne sont pas pénalisées. Donc, évitez $&, $' et $` si vous pouvez, mais si vous ne le pouvez pas, une fois que vous les avez utilisées, utilisez-les comme vous voulez, car vous en avez déjà payé le prix. Souvenez-vous que certains algorithmes les apprécient vraiment. À partir de la version 5.005, la variable $& n'a plus le même coût que les deux autres.
\G
dans une expression rationnelle ?La notation \G
est utilisée dans une reconnaisssance ou
substitution en conjonction avec le modificateur /g
(et ignoré s'il
n'y a pas de /g
) pour ancrer l'expression rationnelle à l'endroit
où la dernière reconnaissance a eu lieu, c'est-à-dire l'endroit
indiqué par pos(). Une correspondance ratée réinitialise la position
de \G
à moins que le modificateur /c
ne soit actif.
Par exemple, supposez que vous ayez une ligne de texte quotée dans un
courrier standard avec la notation Usenet (c.-à-d., commençant par des
>
), et que vous vouliez changer chaque caractère de début
>
en :
. Vous pouvez ainsi faire :
s/^(>+)/':' x length($1)/gem;
Ou, en utilisant \G
, plus simple (et plus rapide) :
s/\G>/:/g;
Une utilisation plus sophistiquée peut entraîner un analyseur
lexicographique. L'exemple suivant, à la lex, est de Jeffrey Friedl.
Il ne marche pas avec la 5.003 à cause d'un bug dans cette version,
mais est ok à partir de la 5.004. (Notez l'utilisation de /c
, qui,
lorsqu'une reconnaissance avec /g
échoue, empêche de remettre la
position de recherche au début de la chaîne).
while (<>) { chomp; PARSER: { m/ \G( \d+\b )/gcx && do { print "nombre: $1\n"; redo; }; m/ \G( \w+ )/gcx && do { print "mot: $1\n"; redo; }; m/ \G( \s+ )/gcx && do { print "espace: $1\n"; redo; }; m/ \G( [^\w\d]+ )/gcx && do { print "autre: $1\n"; redo; }; } }
Bien sûr, cela pourrait avoir été écrit ainsi
while (<>) { chomp; PARSER: { if ( /\G( \d+\b )/gcx { print "nombre: $1\n"; redo PARSER; } if ( /\G( \w+ )/gcx { print "mot: $1\n"; redo PARSER; } if ( /\G( \s+ )/gcx { print "espace: $1\n"; redo PARSER; } if ( /\G( [^\w\d]+ )/gcx { print "autre: $1\n"; redo PARSER; } } }
Mais vous perdez l'alignement vertical des expressions régulières.
Bien qu'il soit vrai que les expressions régulières de Perl ressemblent aux AFD (automate fini déterminé) du programme egrep(1), elles sont dans les faits implémentées comme AFN (automate fini indéterminé) pour permettre le retour en arrière et la mémorisation de sous-motif. Et elles ne sont pas non plus conformes à POSIX, car celui-ci garantit le comportement du pire dans tous les cas. (Il semble que certains préfèrent une garantie de conhérence, même quand ce qui est garanti est la lenteur). Lisez le livre ``Mastering Regular Expressions'' (from O'Reilly) par Jeffrey Friedl pour tous les détails que vous pouvez espérer connaître sur ces matières (la référence complète est dans the perlfaq2 manpage).
Grep et map construisent tous les deux une liste qu'ils retournent, sans tenir compte du contexte. Cela signifie que vous mettez Perl dans le trouble de construire une liste que vous allez ensuite ignorer. Ce n'est pas une façon de traiter un langage de programmation, espèce de petit bandit !
C'est dur et il n'y a pas de bonne manière. Perl ne supporte pas directement les grands caractères. Il prétend qu'un octet et un caractère sont synonymes. L'ensemble d'approches suivantes est offert par Jeffrey Friedl, dont l'article dans le numéro 5 du Perl Journal parle de cela de manière détaillée.
Supposons que vous ayez un codage de ces mystérieux Martiens où les paires de lettre majuscules ASCII codent une lettre simple martienne (i.e. les 2 octets ``CV'' donne une simple lettre martienne, ainsi que ``SG'', ``VS'', ``XX'', etc.). D'autres octets représentent de simples caractères comme l'ASCII.
Ainsi, la chaîne martienne ``Je suis CVSGXX!'' utilise 15 octets pour coder les 12 caractères 'J', 'e', ' ', 's', 'u', 'i', 's', ' ', 'CV', 'SG', 'XX', '!'.
Maintenant, vous voulez chercher le simple caractère /GX/
. Perl ne
connaît rien au martien, donc il trouvera les 2 octets ``GX'' dans la
chaîne ``Je suis CVSGXX!'', alors que ce carctère n'y est pas: il semble
y être car ``SG'' est à côté de ``XX'', mais il n'y a pas de réel
``GX''. C'est un grand problème.
Voici quelques manières, toutes pénibles, de traiter cela :
$martian =~ s/([A-Z][A-Z])/ $1 /g; # assurer que les octets ``martiens'' # ne soient plus contigüs print "GX trouvé!\n" if $martian =~ /GX/;
Ou ainsi :
@chars = $martian =~ m/([A-Z][A-Z]|[^A-Z])/g; # c'est conceptuellemnt similaire à: @chars = $text =~ m/(.)/g; # foreach $char (@chars) { print "GX trouvé!\n", last if $char eq 'GX'; }
Ou encore ainsi :
while ($martian =~ m/\G([A-Z][A-Z]|.)/gs) { # \G probablement inutile print "GX trouvé!\n", last if $1 eq 'GX'; }
Ou encore ainsi :
die "désolé, Perl ne supporte pas (encore) le Martien )-:\n";
Il y a plusieurs double- (et multi-) octets codages couramment utilisés en ce moment. Plusieurs versions de ceux-ci ont des caractères de 1-, 2-, 3- et 4-octets, tous mélangés.
Eh bien, si c'est vraiment un motif, alors utilisez juste
chomp($pattern = <STDIN>); if ($line =~ /$pattern/) { }
Ou, puisque vous n'avez aucune garantie que votre utilisateur a entré une expression rationnelle valide, piégez l'exception de cette façon :
if (eval { $line =~ /$pattern/ }) { }
Mais si vous voulez seulement chercher une chaîne et non pas un motif,
alors vous devriez soit utiliser la fonction index(), qui est faite
pour cela, soit, s'il est impossible de vous convaincre de ne pas
utiliser une expression rationnelle pour autre chose qu'un motif,
assurez-vous au moins d'utiliser \Q
...\E
, documenté dans
the perlre manpage.
$pattern = <STDIN>;
open (FILE, $input) or die "Couldn't open input $input: $!; aborting"; while (<FILE>) { print if /\Q$pattern\E/; } close FILE;
Copyright (c) 1997-1999 Tom Christiansen et Nathan Torkington. Tous droits réservés.
Lorsque ce travail est inclus comme un élément de la distribution standard de Perl, ou comme une partie de sa documentation complète sous forme imprimée ou autrement, il ne peut être distribué que dans les limites fixées par la Perl's Artistic License. Toute distribution de ce fichier ou de ses dérivés hors de cet ensemble nécessite un accord particulier avec le titulaire des droits.
Indépendemment de sa distribution, tous les exemples de code de ce fichier sont ici placés dans le domaine public. Vous êtes autorisés et encouragés à utiliser ce code dans vos programmes que ce soit pour votre plaisir ou pour un profit. Un simple commentaire dans le code précisant l'origine serait de bonne courtoisie mais n'est pas indispensable.
La traduction française est distribuée avec les même droits que sa version originale (voir ci-dessus).
Cette traduction française correspond à la version anglaise distribuée avec perl 5.6.0. Pour en savoir plus concernant ces traductions, consultez http://perl.enstimac.fr/.
Marianne Roger <maroger@maretmanu.org>, Roland Trique <roland.trique@uhb.fr> (mise à jour).
Régis Julié (Regis.Julie@cetelem.fr), Gérard Delafond.
NOM |