Perl : Notions avancées

Slides:



Advertisements
Présentations similaires
Les Structures.
Advertisements

Premier programme en C :
Portée des variables VBA & Excel
Fonctions & procédures
La classe String Attention ce n’est pas un type de base. Il s'agit d'une classe défini dans l’API Java (Dans le package java.lang) String s="aaa"; // s.
Chapitre 2 :Tableaux Pr. Aissam MESRAR Ecole ESIAM.
GEF 243B Programmation informatique appliquée Types dérivés, structures et tableaux §
(Classes prédéfinies – API Java)
Cours n°2M2. IST-IE (S. Sidhom) UE 303 Promo. M2 IST-IE 2005/06 Conception dun système d'information multimédia Architecture trois-tiers : PHP/MySQL &
Bioinformatique et Perl
C.
Personal Home Page / Hypertext Processor (PHP)
Objectifs Présentation et utilisation du langage PERL
Chap. 1 Structures séquentielles : listes linéaires
Introduction : Compilation et Traduction
ESIEE Paris © Denis BUREAU I N Initiation à la programmation avec le langage Java.
FLSI602 Génie Informatique et Réseaux
La fonction Style Permet de créer des types de texte, par exemple
Algorithme et programmation
Les sous-programmes Chapitre n° 5: Objectifs : Activité:
Les fonctions.
Introduction à l'informatique linguistique
CPI/BTS 2 Programmation Web Introduction au PHP
Cours 7 - Les pointeurs, l'allocation dynamique, les listes chaînées
Introduction : Compilation et Traduction
Les méthodes en java Une méthode est un regroupement d’instructions ayant pour but de faire un traitement bien précis. Une méthode pour être utilisée.
8PRO100 Éléments de programmation Comment faire prendre une décision à un ordinateur?
Les structures de données arborescentes
Analyse lexicale Généralités Expressions rationnelles Automates finis
Leçon 6 : Structures de données dynamiques IUP 2 Génie Informatique Méthode et Outils pour la Programmation Françoise Greffier.
28 novembre 2012 Grégory Petit
SELECT {* | Expression [Alias] [,...] } FROM Table [WHERE Condition] [ORDER BY { Expression | Alias } [ ASC | DESC ] [NULLS FIRST | NULLS LAST ] [,...]
Python La programmation objet
Complément Le diagramme des classes
Les pointeurs Modes d’adressage de variables. Définition d’un pointeur. Opérateurs de base. Opérations élémentaires. Pointeurs et tableaux. Pointeurs et.
Ensembles Définition d’un ensemble. Opérations sur les ensembles. Accès, suppression et ajout d’éléments d’un ensemble. Fonctions permettant de manipuler.
Une nouvelle structure de données : les tableaux
Manipulation de formulaires en Javascript
Perl, un langage de programmation pour les données textuelles
Expressions régulières et hash tables
Les Fonctions. Définir une fonction Sections de code indépendantes que lon peut appeler à nimporte quel moment et dans nimporte quel ordre. Bout de code.
Introduction à la programmation I Fonctions Structures de contrôle Structures de données (arrays simples et indexés) Variables locales et globales.
1 GPA435 Systèmes dexploitation et programmation de système Copyright, 2000 © Tony Wong, Ph.D. Chapitre 9 Programmation nawk(1)
Eric Laporte Institut Gaspard-Monge Université de Marne-la-Vallée France Introduction à Perl.
1.1 LES VECTEURS GÉOMÉTRIQUES
IFT 6800 Atelier en Technologies d’information
8PRO107 Éléments de programmation
Chapitre 9 Les sous-programmes.
Chapitre 3 Syntaxe et sémantique.
CSI3525: Concepts des Langages de Programmation Notes # 6: Langages de Programmation Fonctionelle II: Introduction au ML.
Structures de données IFT-10541
Chapitre 3 Les bibliothèques de balises JSP et la JSTL
Mise en forme en Mathématiques
1 GPA435 Systèmes d’exploitation et programmation de système Copyright, 2000 © Tony Wong, Ph.D. Chapitre 8 Filtres UNIX.
Animateur : Med HAIJOUBI
Structures des données
Expressions régulières et hash tables
LES PILES ET FILES.
Chapitre 3 :Algèbre de Boole
Master 1 SIGLIS Java Lecteur Stéphane Tallard Les erreurs communes en Java.
 Syntaxe du langage PHP
420-B63 Programmation Web Avancée Auteur : Frédéric Thériault 1.
420-B63 Programmation Web Avancée Auteur : Frédéric Thériault 1.
Cours LCS N°4 Présenté par Mr: LALLALI
06:34:37 Programmation Web PHP Fonctions associées aux tableaux Jérôme CUTRONA
Tutorat en bio-informatique Le 12 octobre Exercices 3 et 4 (MAT1400) - solutions La série du binôme (chap. 8.8) –Trouver la série entière et le.
Mettre en formeExaminerManipuler Les fonctions printf() et sprintf Le traitement de chaîne de caractère La fonction printf() formate le contenu d'une chaîne.
1. Spoon Christophe Delagarde, septembre 1998 I.U.T., Université de la Méditerrainée 2.
8PRO107 Éléments de programmation Les tableaux. Étude de cas 1 Description du problème : Lire une liste d’entiers et l’afficher d’abord dans le même ordre.
Introduction à l’utilitaire
Transcription de la présentation:

Perl : Notions avancées Expressions rationnelles/régulières Utilisation en Perl Tableaux associatifs Fonctions prédéfinies

Perl : expressions régulières Perl offre une grande puissance de manipulation d'expressions régulières. En Perl on utilise les expression régulières en tant que motifs de recherche. On utilise l'opérateur conditionnel =~ qui signifie « ressemble à » (matches). Syntaxe : $chaîne =~ /expression/ Exemple : if ($nom =~ /^[Dd]upon/) {print "OK !";} => Ok si nom est 'dupont', 'dupond', 'Dupont-Lassoeur' ^ signifie « commence par » On peut rajouter i derrière l'expression pour signifier qu'on ne différencie pas les majuscules des minuscules. Le contraire de l'opérateur =~ est !~ (ne ressemble pas à ...) if ($nom !~ /^dupon/i) {print "Non...";}

Perl : expressions régulières \s = espace ou tabulation ou retour-chariot « white space » \n = retour-chariot \t = tabulation ^ = début de chaîne $ = fin de chaîne a = a . = un caractère quelconque (sauf fin de ligne) Documentation complète: « perldoc perlre » ou http://www.perldoc.com/perl5.8.0/pod/perlre.html ou http://perl.asylog.net/DocFr/perlre.html

Perl : expressions régulières [a-z] tout caractère minuscule [aeiouy] toute voyelle [a-zA-Z0-9] tout caractère alphanumérique ^ au début d'un ensemble indique le complément de l'ensemble [^0-9] tout caractère non numérique \w un caractère alphanumérique ou _ (sans à, é, etc.) \W tout sauf un \w \d un chiffre (= [0-9]) \D tout sauf un \d (= [^0-9]) \S tout sauf un \s \b début ou fin d’un mot, soit entre \w et \W ou vice versa (utile surtout en anglais)

Perl : expressions régulières Quelques opérateurs : « ? » 0 ou 1 fois, a? = 0 ou 1 a « * » 0 fois ou plus, a* = 0 ou plusieurs a « + » 1 fois ou plus, a+ = 1 ou plusieurs a (ab)+ = 1 ou plusieurs ab « | » : ou (inclusif) a|b = a ou b [^abc] tous caractères qui ne sont pas a ou b ou c {n,m} de n à m fois a{1,4} = 1 à 4 a {n,} n fois ou plus a{3,} = 3 a ou plus

Perl : expressions régulières Remarque : Si l'on veut qu'un méta-caractère apparaisse tel quel, il faut le précéder d'un « back-slash » (\). Les méta-caractères sont : . ^ | ( ) [ ] { } \ / $ + * ? ex : if (/\(.*\)/) {print;} affiche toute ligne contenant des parenthèses

Perl : expressions régulières – exemples Pour vérifier si une chaîne $x contient la chaîne "abc'' if ($x =~ /abc/) { . . . } Pour vérifier si une chaîne $x commence par la chaîne "abc'' if ($x =~ /^abc/) { . . . } Pour vérifier si une chaîne $x commence par une majuscule if ($x =~ /^[A-Z]/) { . . . } Pour vérifier si une chaîne $x ne commence pas par une minuscule if ($x =~ /^[^a-z]/) { . . . } Ici le premier ^ signifie le début de la chaîne, tandis que le deuxième ^ à l'intérieur des crochets indique le complément de l'ensemble indiqué.

Perl : Remplacement Perl permet de faire des remplacements sur une chaîne des caractères, en utilisant la syntaxe : $chaîne =~ s/motif/remplacement/; où motif est une expression régulière et remplacement ce qui remplace. Exemples : $fruit =~ s/e$/es/; remplace un e final par es $tel =~ s/^99\./02.99\./; remplace des numéros de téléphone par une nouvelle numérotation

Perl : Remplacement On peux référencer une partie du motif dans le remplacement avec $1 ($1 est une variable correspondant au contenu de la première parenthèse). Exemple : Transformer automatiquement les noms d'arbres par « arbre à fruit » $texte =~ s/([a-z]+)ier /arbre à $1es /; 'cerisier' sera traduit par 'arbre à cerises' (contenu de $1 => 'ceris') 'manguier' => 'arbre à mangues' $2 correspond à la deuxième parenthèse, $3 à la troisième etc. Les options s/exp/remp/i; => Indifférenciation minuscules/majuscules s/exp/remp/g; => Remplace toutes les occurrences (pas seulement la première) Exemple : Pour remplacer un texte par le même en majuscule (\U) s/([a-z])/\U$1/g;

Perl : Remplacement Pour remplacer les suites de plusieurs a en un seul a : $x =~ s/a+/a/g; Pour enlever les suites de a : $x =~ s/a*//g; Ou tout simplement : $x =~ s/a//g; Pour enlever les espaces au début d'une chaîne : $x =~ s/^\s+//; Et à la fin de la chaîne : $x =~ s/\s+$//;

Perl : Remplacement – exemple complexe Supposons qu’on ait un texte en anglais américain étiqueté et qu’on veuille le convertir en anglais britannique. Plus précisément, on veut trouver les verbes en « -ize » et les réécrire « -ise », mais seulement ceux avec un radical d’au moins 5 lettres. Par exemple : USA : Analyzing the situation, he finalized his conclusions and sized the problem. R.U. : Analysing the situation, he finalised his conclusions and sized the problem. Le texte étant étiqueté, l’entrée du programme sera : Analyzing/VBG the/DT situation/NN ,/, he/PRP finalized/VBD his/PRP$ conclusions/NNS and/CC sized/VBD the/DT problem/NN ./.

Perl : Remplacement – exemple complexe Première solution : Solution avancée et plus facile à lire :

Perl : Remplacement – exemple complexe Première solution (corrigée): s/(^| )(\w{4,}[b-df-hj-np-tv-xz][iy])z(e|es|ed|ing)\/VB/$1$2s$3\/VB/g; Solution avancée et plus facile à lire : s/ \b # début du mot (\w{4,}) # $1 : 4 lettres ou plus ([b-df-hj-np-tv-xz][iy]) # $2 : un consonne et i ou y z # le z (e|es|ed|ing) # $3 : terminaison conjuguée (?=\/VB) # assertion « vide » : étiquette d’un verbe /$1$2s$3/gx;

Les tableaux associatifs Les tableaux sont des structures qui consistent de paires de clés et valeurs. La clé est toujours un index numérique. Les index sont consécutifs. Les tableaux associatifs sont des structures qui consistent de paires de clés et valeurs où les clés ne sont pas nécessairement numériques ni consécutives (et donc sans ordre prédéfini). Ils sont toujours précédés du caractère % : my %prix = (’amande’, 30, ’fraise’, 9, ’cerise’, 25); ou my %prix = (’amande’ => 30, ’fraise’ => 9, ’cerise’ => 25); On fait ensuite référence à un élément du tableau par : $prix{’cerise’}

Les tableaux associatifs Exemples : my %chiffre = (); $chiffre{’un’} = 1; $chiffre{’deux’} = 2; print $chiffre{’deux’}; => 2 my $var = ’un’; print $chiffre{$var}; => 1 Remarque les tableaux associatifs utilisent les accolades, tandis que les tableaux utilisent les crochets. Donc, $x{2} retourne la valeur associée à la clé 2 dans le tableau associatif %x, tandis que $x[2] retourne le troisième élément du tableau @x. Attention : $x, @x et %x peuvent exister en même temps—ce sont trois variables distinctes!

Les tableaux associatifs Pour afficher toutes les clefs et les valeurs d'un tableau associatif, while ( my ($key,$val) = each %thearray ) { print $key, " ", $val, "\n"; } ou foreach my $key ( keys %prix ) { print $key, " ", $prix{$key}, "\n"; Le code utilisant « each » est un peu plus rapide, mais celui utilisant « keys » permet de trier les clés avant de les imprimer : foreach my $key ( sort keys %prix ) {

Exemple – fréquence des mots d'un texte #!/usr/bin/perl -w use strict; use warnings; # toujours utiliser ces deux instructions!!! $/ = ""; # unité de travail : le paragraphe my %wordcount; while (<>){ s/-\n//g; # enlever les tirets tr/A-Z/a-z/; # minusculiser my @words = split /\W*\s+\W*/, $_; foreach my $word (@words) { $wordcount{$word}++; } foreach my $word (sort keys (%wordcount)) { printf "%20s,%d\n",$word,$wordcount{$word};

Exemple – fréquence des bigrammes d'un texte #!/usr/bin/perl -w use strict; use warnings; $/ = ""; my %wordcount; while (<>) { s/-\n//g; s/^\s+//; tr/A-Z/a-z/; my @words = split /\W*\s+\W*/, $_; for ( my $count = 0; $count <= $#words-1; $count++ ) { $wordcount{"$words[$count] $words[$count+1]"}++; } foreach $wordpair (sort keys %wordcount) { printf "%20s,%d\n", $wordpair, $wordcount{$wordpair};

Exemple – fréquence des terminaisons (3 cars) my %ending; while(<>) { s/^\s+//; my @words = split(/\s+/,$_); foreach my $count (0 .. $#words) { # syntaxe plus pratique que for my @chars = split(//,$words[$count]); # on split sans séparateur # le résultat est un tableau de caractères if ($#chars > 1) { # on vérifie qu'il y ait au moins trois caractères $ending{$chars[$#chars-2] . " " . $chars[$#chars-1] . " " . $chars[$#chars]}++; } } } foreach my $end (sort keys %ending) { printf "%20s,%d\n", $end, $ending{$end}; }

Exemple – POS stripping Étant donné un texte étiqueté avec partie du discours (Parts-Of-Speech) The/det boy/noun ate/verb . . . enlever les partie du discours while(<>) { s/^\s+//; my @words = split; # paramètres implicites: (/\s+/,$_); for (my $count=0; $count<=$#words; ++$count) { my $word = $words[$count]; # mais il faut enlever l'étiquette $word =~ s/\/.*$//; # si une chaîne commence avec un slash, et elle comporte # une suite de caractères, la remplacer avec la chaîne # vide. Ne pas oublier : il faut annuler l’interprétation # habituelle du méta-caractère / en le précédant de \. print $word, " "; } print "\n"; }

Exemple – mots stripping Étant donné un texte étiqueté avec partie du discours (Parts-Of-Speech) The/det boy/noun ate/verb . . . enlever les mots et retourner les parties du discours while(<>) { s/^\s+//; my @words = split; foreach my $word (@words) {# syntaxe encore plus simple $word =~ s/^.*\///; # enlever le mot lui-même print $word, " "; } print "\n"; }

Exemple – le mot le plus long dans un texte my $maxlength = 0; my $longestword; while(<>) { my @words = split(/\s+/,$_); foreach my $word (@words) { @chars = split(//,$word); if ($#chars > $maxlength) { $maxlength = $#chars; $longestword = $word; } } } $maxlength++; #il faut ajouter 1, car l’indice commence à 0 print "$longestword $maxlength\n";

Exemple – trigrammes #!/usr/bin/perl –w use strict; use warnings; $/ = ""; # Tallies trigrams in each line Parens are ignored # Default input from STDIN Default output to STDOUT. my %count; while (<>) { s/\(/ /g; s/\)/ /g; # remove parens and tokenize my @token = split; # split on whitespace # count trigrams for (my $i=0; $i < @token - 2; $i++) { # Attention: @token - 2??? $count{"$token[$i] $token[$i+1] $token[$i+2]"}++; } # output while (my ($key, $value) = each %count) { print "$value $key\n";

Exemple – 4-grammes #!/usr/bin/perl -w use strict; use warnings; $/ = ""; # Tallies 4-grams in each line Parens are ignored # Default input from STDIN Default output to STDOUT. my %count; while (<>) { # remove parens and tokenize s/\(/ /g; s/\)/ /g; my @token = split; # count 4-grams foreach my $i (0 .. $#token - 3) { $count{"@token[$i..$i+3]"}++; # Comment ça marche, ça??? } # output while (my ($key, $value) = each %count) { print "$value $key\n";

Exemple – unique #!/usr/bin/perl –w use strict; use warnings; # Eliminates all but the first occurrence of each line in a file # without otherwise changing the order. my %seen; while (<>) { if ($seen{$_}) { next; } else { $seen{$_}++; print; }

Passage de paramètres au programme En Unix/Linux/Cygwin on peut appeler un programme Perl en lui donnant des paramètres, comme on le fait pour les commandes Unix. Les paramètres sont stockés dans un tableau spécial : @ARGV Le premier paramètre est donc $ARGV[0] $#ARGV est l'indice du dernier élément du tableau @ARGV, donc $ARGV[$#ARGV] est la valeur du dernier élément du tableau Exemple open(P, $ARGV[0]) || die "Couldn't open $ARGV[0]: $!";

Paramètres : options avancées Le module Perl Getopt::Long nous permet de spécifier facilement une série de paramètres aussi complexe qu’on le veut. Voire « perldoc Getopt::Long » ou http://www.perldoc.com/perl5.6.1/lib/Getopt /Long.html pour la documentation complète. Exemple : sub usage { print STDERR "Usage: $0 [-debug] [-count <n>] [-help] [-outfile <filename>] <infile>\n"; exit 1; } my $debug = 0; my $outfile = ""; my $help; my $count = 0; GetOptions(debug => \$debug, help => \$help, "outfile=s" => \$outfile, "count=i" => \$count, ) or usage; # Exit avec message en cas d’erreur # Maintenant, $debug, $outfile, $help et $count contiennent # les valeurs que l’usager a spécifiées pour les paramètres. $help and usage; # Exit avec message si l’usager tape -h my $infile = shift; # shift fournit le paramètre suivant

Fonctions prédéfinies – chaînes de caractères chop(ch) Enlève le dernier caractère de la chaîne ch. $ch=’cerises’; chop($ch);=> ch contient 'cerise‘ while(<>){chop; …} => le retour de chariot est enlevé de $_ chomp(ch) Même chose que « chop » mais enlève uniquement un retour de chariot en fin de chaîne. length(ch) Retourne le nombre de caractères de la chaîne ch. length(’cerise’) => 6 uc(ch) Retourne la chaîne ch en majuscules. $ch = uc(’poire’) => 'POIRE' $ch = uc(’PoIrE’) => 'POIRE' lc(ch) Retourne la chaîne ch en minuscules. $ch = lc(’POIRE’) => 'poire'

Fonctions prédéfinies – chaînes de caractères substr(ch, début, longueur) Retourne la chaîne de caractère contenue dans ch, commençant au caractère à l’indice début et de longueur longueur. $ch=substr(’dupond’, 0, 3) => 'dup' $ch=substr(’Les fruits’, 4) => 'fruits' index(ch, sousch, début) Retourne la position de la première instance de sousch dans ch. Si début est spécifié, il spécifie la position de départ pour la recherche. $i=index(’Le temps des cerises’, ’cerise’); => 13

Fonctions prédéfinies – tableaux, listes my @fruits = (’amande’, ’fraise’, ’cerise’); pop (tableau) Enlève et retourne le dernier élément de tableau. print pop(@fruits); => affiche 'cerise', @fruits devient ('amande','fraise') push (tableau, élément) Ajoute élément à la fin de tableau (contraire de pop). push(@fruits, ’abricot’); => @fruits devient ('amande','fraise','abricot') shift(tableau) Enlève et retourne le premier élément de tableau. print shift(@fruits) => Affiche 'amande', @fruits devient ('fraise','abricot') unshift (tableau, élément) Ajoute élément au début de tableau. unshift(@fruits, ’poire’); => @fruits devient ('poire','fraise','abricot')

Fonctions prédéfinies – tableaux, listes sort (tableau) Trie le tableau (en ordre ASCII croissant par défaut). @fruits = sort (@fruits); => @fruits devient ('abricot', 'fraise‘, ‘poire’) @fruits = sort {$b cmp $a} @fruits; # Tri inverse => @fruits devient (‘poire’, 'fraise‘, 'abricot') sort (10, 3, 5) => (10, 3, 5) # Tri ASCII sort {$a <=> $b} (10, 3, 5) => (3, 5, 10) # Tri numérique sort {$b <=> $a} (10, 3, 5) => (10, 5, 3) # Tri numérique inverse sort {$a cmp $b} (’e’, ’C’, ’a’) => (‘C’, ‘a’, ‘e’) # Tri ASCII sort (’e’, ’C’, ’a’) => (‘C’, ‘a’, ‘e’) # Tri ASCII sort {lc($a) cmp lc($b)} (’e’, ’C’, ’a’) => (‘a’, ‘C’, ‘e’) reverse (tableau) Inverse le tableau. @fruits = reverse(@fruits); => @fruits redevient ('abricot', 'fraise‘, ‘poire’)

Fonctions prédéfinies – tableaux, listes splice (tableau, début, nb, liste) Remplace nb éléments de tableau à partir de l'indice début avec les éléments dans liste. Retourne un tableau contenant les éléments enlevés. si @fruits = ('poire', 'fraise', 'abricot', 'cerise') et @legumes = ('carotte', 'tomate', 'céleri') @fruits2 = splice(@fruits, 1, 2, @legumes); => @fruits = ('poire', 'carotte', 'tomate', 'céleri', 'cerise') @fruits2 = ('fraise', 'abricot')

Fonctions prédéfinies – tableaux, listes splice (tableau, début, nb, liste) Dans les cas limites, on peut utiliser splice au lieu de shift, pop, unshift et push. $a = shift(@abz) $a = splice(@abz,0,1) $z = pop(@abz) $z = splice(@abz,$#abz,1) unshift (@abz,$a) splice(@abz,0,0,$a) push(@abz,$z) splice(@abz,$#abz+1,0,$z) substr (ch, début, longueur, remplacement) Si on spécifie un remplacement, comme avec splice, la sous chaîne est remplacée par remplacement. my $ch = "abcdef"; substr($ch, 2, 3, "12345"); => $ch = “ab12345f” substr($ch, 2, 3) = "12345"; # Code équivalent

Exemple – blankwords #!/usr/bin/perl –w use strict; use warnings; # blanks out given words # the words to remove should be in a file, one per line # check for correct usage if ($#ARGV < 0) { # pas de params print STDERR "usage: blankwords <word list> [<base file(s)>]\n"; exit 1; } open(P, $ARGV[0]) or die "Couldn't open killword file $ARGV[0]: $!"; my $killwords = "\n"; while (<P>) { $killwords .= $_; # $var OP= $val equivaut à $var = $var OP $val close(P); shift; # s'applique à @ARGV

Exemple – blankwords while (<>) { my @token = split; # split on whitespace my @char = split("", $_); # split on nullspace to get char array my $offset = 0; for ( my $i = 0; $i < @token; $i++ ) { $offset = index($_, $token[$i], $offset); my $size = length($token[$i]); my $pat = "\Q$token[$i]\E"; # \Q quotes meta chars until \E if ($killwords =~ /\n$pat\n/) { foreach my $ind ($offset .. $offset + $size - 1) { splice(@char, $ind, 1, " "); # avec splice } # avec substr: substr($_, $offset, $size, " " x $size); $offset += $size; print @char; # avec splice # avec substr: print $_;

Exemple – blankclasses #!/usr/bin/perl –w use strict; use warnings; # Blanks out words of a given POS in a tagged text the POS to remove # should be in a file, one per line. Words and tags are separated by :: # check for correct usage if ($#ARGV < 0) { print STDERR "usage: blankclasses <POS list> [<base file>]\n"; exit 1; } open(P, $ARGV[0]) or die "Couldn't open POS-list file $ARGV[0]: $!"; my $killclasses = "\n"; while (<P>) { $killclasses .= $_; close(P); shift;

Exemple – blankclasses while (<>) { s/^ *//; # enlever les espace au début de ligne my @token = split; # split on whitespace for (my $i = 0; $i < @token; $i++) { # @token: scalar context if ($token[$i] =~ /(.+)::(.+)/) { # word::tag and back-ref my $word = $1; my $tag = $2; if ($killclasses =~ /\n$tag\n/) { $token[$i] = " " x length($token[$i]); } } else { die "Word or Tag missing from token $token[$i]\n"; print join(' ', @token), "\n";