ludovic tanguy, nabil hathout-perl pour les linguistes-hermès (2007)

496
Perl pour les linguistes Programmes en Perl pour exploiter les données langagières Ludovic Tanguy et Nabil Hathout

Upload: scripio

Post on 08-Dec-2015

45 views

Category:

Documents


3 download

DESCRIPTION

Perl pour les linguistes

TRANSCRIPT

Page 1: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Perl pour les linguistesProgrammes en Perl pour exploiter les données langagières

Ludovic Tanguy et Nabil Hathout

Page 2: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

2

Page 3: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

TABLE DES MATIÈRES

Liste des programmes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

Chapitre 1. Données . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

1.1. Exemples de données . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351.2. Exemple d’utilisation de données pour des recherches en linguistique . 381.3. Présentation du chapitre . . . . . . . . . . . . . . . . . . . . . . . . .. . 391.4. Formats de documents électroniques . . . . . . . . . . . . . . . .. . . . 40

1.4.1. Le format texte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 401.4.2. Les autres formats de document et leur conversion en texte . . . . 451.4.3. Les archives compressées . . . . . . . . . . . . . . . . . . . . . . .52

1.5. Panorama des ressources disponibles . . . . . . . . . . . . . . .. . . . . 551.5.1. Les ressources textuelles . . . . . . . . . . . . . . . . . . . . . .. . 551.5.2. Les ressources lexicales . . . . . . . . . . . . . . . . . . . . . . .. 63

1.6. Obtenir une ressource . . . . . . . . . . . . . . . . . . . . . . . . . . . .721.6.1. Identifier et localiser les ressources à utiliser . . .. . . . . . . . . 721.6.2. Télécharger des documents en grand nombre . . . . . . . . .. . . 73

1.7. Segmentation, catégorisation et lemmatisation des textes . . . . . . . . 751.7.1. Segmentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 751.7.2. Catégorisation et lemmatisation . . . . . . . . . . . . . . . .. . . 761.7.3. TreeTagger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

Chapitre 2. Environnement de travail et notions de système. . . . . . . . . 83

2.1. Environnement de travail initial . . . . . . . . . . . . . . . . . .. . . . . 832.1.1. Pour Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 842.1.2. Pour Unix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 852.1.3. ActivePerl (Windows) . . . . . . . . . . . . . . . . . . . . . . . . . 85

2.2. Fichiers, répertoires et volumes . . . . . . . . . . . . . . . . . .. . . . . 86

11

Page 4: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

12 Perl pour les linguistes

2.2.1. Explorateur Windows . . . . . . . . . . . . . . . . . . . . . . . . . 872.2.2. Types de fichiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

2.3. Le système d’exploitation « en direct » . . . . . . . . . . . . . .. . . . . 892.3.1. Terminal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 892.3.2. Ligne de commande . . . . . . . . . . . . . . . . . . . . . . . . . . 90

2.4. Chemins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 912.4.1. Chemin absolu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 912.4.2. Répertoire de travail . . . . . . . . . . . . . . . . . . . . . . . . . .922.4.3. Chemin relatif . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 942.4.4. Changement de répertoire de travail (cd) . . . . . . . . . . . . . . 94

2.5. Lancement des programmes Perl . . . . . . . . . . . . . . . . . . . . .. 952.6. Entrées/sorties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .97

2.6.1. Flux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 982.6.2. Redirections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 982.6.3. Tube (pipe) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1002.6.4. Affichage paginé (more) . . . . . . . . . . . . . . . . . . . . . . . . 101

2.7. Complément de l’environnement de travail . . . . . . . . . . .. . . . . 1022.7.1. 7-Zip (Windows) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1022.7.2. Editeur de texteSciTE . . . . . . . . . . . . . . . . . . . . . . . . . 1032.7.3. Installation des modules supplémentaires . . . . . . . .. . . . . . 1042.7.4. Aide en ligne (perldoc) . . . . . . . . . . . . . . . . . . . . . . . . 1062.7.5. Adaptation des environnements Unix . . . . . . . . . . . . . .. . 1062.7.6.TreeTagger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1072.7.7.Morphalou . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110

2.8. Aborder la suite de l’ouvrage . . . . . . . . . . . . . . . . . . . . . .. . 111

Chapitre 3. Les bases de Perl . . . . . . . . . . . . . . . . . . . . . . . . . . . 113

3.1. Quelques principes du langage Perl . . . . . . . . . . . . . . . . .. . . . 1133.2. Premier programme Perl . . . . . . . . . . . . . . . . . . . . . . . . . . .114

3.2.1. Lancement et déroulement du programme . . . . . . . . . . . .. . 1153.2.2. Accès au code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1163.2.3. Description du code . . . . . . . . . . . . . . . . . . . . . . . . . . 116

3.3. Syntaxe de base de Perl . . . . . . . . . . . . . . . . . . . . . . . . . . . 1203.4. Version simplifiée et raccourcie du premier programme .. . . . . . . . 1223.5. Structures de contrôle : instructions conditionnelles . . . . . . . . . . . 123

3.5.1. Simplification des conditionnelles imbriquées parelsif . . . . . . 1273.5.2. Syntaxe des conditions . . . . . . . . . . . . . . . . . . . . . . . . .128

3.6. Structures de données . . . . . . . . . . . . . . . . . . . . . . . . . . . .1313.6.1. Tableaux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1313.6.2. Hachages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135

3.7. Structures de contrôle : boucles . . . . . . . . . . . . . . . . . . .. . . . 1373.7.1. Boucleswhile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1373.7.2. Bouclesfor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143

Page 5: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Table des matières 13

3.7.3. Bouclesforeach . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1453.8. Manipulation de fichiers . . . . . . . . . . . . . . . . . . . . . . . . . .. 147

3.8.1. Lecture d’un fichier texte . . . . . . . . . . . . . . . . . . . . . . .1483.8.2. Ecriture dans un fichier texte . . . . . . . . . . . . . . . . . . . .. 151

3.9. Arguments d’un programme . . . . . . . . . . . . . . . . . . . . . . . . .1553.10. Fonctions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1563.11. Autres notions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159

3.11.1. Erreurs de programmation . . . . . . . . . . . . . . . . . . . . . .1593.11.2. Autres composants du langage Perl . . . . . . . . . . . . . . .. . 161

Chapitre 4. Expressions régulières . . . . . . . . . . . . . . . . . . . . . . . . 163

4.1. Généralités et définition . . . . . . . . . . . . . . . . . . . . . . . . .. . 1634.2. Expressions régulières de base . . . . . . . . . . . . . . . . . . . .. . . 164

4.2.1. Principe de correspondance . . . . . . . . . . . . . . . . . . . . .. 1644.2.2. Anatomie d’une expression régulière . . . . . . . . . . . . .. . . . 1644.2.3. Expressions atomiques . . . . . . . . . . . . . . . . . . . . . . . . .1654.2.4. Concaténation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1654.2.5. Disjonction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1654.2.6. Critères de position . . . . . . . . . . . . . . . . . . . . . . . . . . .1654.2.7. Fermeture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1664.2.8. Parenthèses et priorité des opérateurs . . . . . . . . . . .. . . . . 1664.2.9. Métacaractères et échappement . . . . . . . . . . . . . . . . . .. . 168

4.3. Expressions régulières étendues . . . . . . . . . . . . . . . . . .. . . . . 1684.3.1. Classes de caractères . . . . . . . . . . . . . . . . . . . . . . . . . .1694.3.2. Fermetures complexes . . . . . . . . . . . . . . . . . . . . . . . . . 1714.3.3. Frontières de mots . . . . . . . . . . . . . . . . . . . . . . . . . . . 172

4.4. Syntaxe Perl pour la correspondance . . . . . . . . . . . . . . . .. . . . 1734.5. Mécanismes de correspondance . . . . . . . . . . . . . . . . . . . . .. . 174

4.5.1. Sous-chaînes de caractères et sous-expressions . . .. . . . . . . . 1754.5.2. Les règles de la correspondance . . . . . . . . . . . . . . . . . .. 1754.5.3. Fermetures non gloutonnes . . . . . . . . . . . . . . . . . . . . . .1774.5.4. Fermetures multiples . . . . . . . . . . . . . . . . . . . . . . . . . .178

4.6. Extraction de sous-chaînes . . . . . . . . . . . . . . . . . . . . . . .. . 1794.6.1. Mémorisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1794.6.2. Autres variables spéciales . . . . . . . . . . . . . . . . . . . . .. . 1824.6.3. Occurrences multiples . . . . . . . . . . . . . . . . . . . . . . . . .182

4.7. Modification de chaînes par substitution . . . . . . . . . . . .. . . . . . 1834.7.1. Principe et syntaxe . . . . . . . . . . . . . . . . . . . . . . . . . . . 1844.7.2. Substitution et mémorisation . . . . . . . . . . . . . . . . . . .. . 185

4.8. Problématiques avancées . . . . . . . . . . . . . . . . . . . . . . . . .. 1864.8.1. Utilisation de variables dans les expressions régulières . . . . . . 1864.8.2. Négation et expressions régulières . . . . . . . . . . . . . .. . . . 189

Page 6: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

14 Perl pour les linguistes

Chapitre 5. Recherche d’unités linguistiques . . . . . . . . . . . . . . . . . . 191

5.1. Généralités . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1915.2. Recherche de mots dans un lexique nu ou un texte segmenté. . . . . . 192

5.2.1. Recherche d’un mot exact . . . . . . . . . . . . . . . . . . . . . . . 1925.2.2. Recherche exacte d’une liste de mots . . . . . . . . . . . . . .. . 1945.2.3. Recherche par expressions régulières . . . . . . . . . . . .. . . . 1965.2.4. Recherche par expressions régulières avec tri des résultats . . . . 199

5.3. Recherche de mots dans un texte étiqueté . . . . . . . . . . . . .. . . . 2015.3.1. Recherche par lemme ou catégorie dans un texte étiqueté . . . . . 2025.3.2. Recherche multicritère par expressions régulières. . . . . . . . . 2055.3.3. Critères de recherche plus complexes . . . . . . . . . . . . .. . . 208

5.4. Recherche de mots ou de séquences de mots dans un texte brut . . . . . 2095.4.1. Recherche d’un mot . . . . . . . . . . . . . . . . . . . . . . . . . . 2095.4.2. Recherche d’une séquence simple de mots . . . . . . . . . . .. . 2115.4.3. Recherche de séquences complexes . . . . . . . . . . . . . . . .. 214

5.5. Recherche de séquences de mots dans un texte étiqueté . .. . . . . . . 2175.5.1. Recherche de séquences de longueur fixe . . . . . . . . . . . .. . 2175.5.2. Recherche de séquences par automates à états finis . . .. . . . . . 219

5.6. Recherche dans un ensemble de fichiers . . . . . . . . . . . . . . .. . . 224

Chapitre 6. Calculs de fréquences . . . . . . . . . . . . . . . . . . . . . . . . 229

6.1. Généralités . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2296.1.1. Les fréquences : de quoi, pourquoi? . . . . . . . . . . . . . . .. . 2296.1.2. Principes généraux du calcul de fréquences : algorithme de base . 230

6.2. Calcul de fréquences simples . . . . . . . . . . . . . . . . . . . . . .. . 2316.2.1. Fréquences des formes fléchies d’un texte segmenté . .. . . . . . 2316.2.2. Fréquences des couples (forme/catégorie) d’un texte étiqueté . . . 2336.2.3. Rang des lemmes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236

6.3. Cooccurrences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2386.3.1. Cooccurrences des formes d’un texte étiqueté . . . . . .. . . . . . 2416.3.2. Cooccurrences des lemmes d’un texte étiqueté après sélectionde la catégorie et filtrage . . . . . . . . . . . . . . . . . . . . . . . . . . . 2446.3.3. Utilisation de mesures statistiques – L’information mutuelle . . . 249

Chapitre 7. Concordances . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255

7.1. Principes de fonctionnement . . . . . . . . . . . . . . . . . . . . . .. . 2557.2. Concordances de formes exactes sur texte brut . . . . . . . .. . . . . . 257

7.2.1. Programme et utilisation . . . . . . . . . . . . . . . . . . . . . . .. 2577.2.2. Détails du programme . . . . . . . . . . . . . . . . . . . . . . . . . 259

Page 7: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Table des matières 15

7.3. Concordances par expressions régulières sur texte brut . . . . . . . . . . 2647.3.1. Programme et utilisation . . . . . . . . . . . . . . . . . . . . . . .. 2657.3.2. Présentation du programme . . . . . . . . . . . . . . . . . . . . . .267

7.4. Autres types de concordancier . . . . . . . . . . . . . . . . . . . . .. . 268

Chapitre 8. Traitements lexicaux . . . . . . . . . . . . . . . . . . . . . . . . . 269

8.1. Extraire un sous-lexique . . . . . . . . . . . . . . . . . . . . . . . . .. . 2718.2. Caractérisation globalement d’un lexique . . . . . . . . . .. . . . . . . 2728.3. Fusion de lexiques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275

8.3.1. Fusion simple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2758.3.2. Fusion avec tri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277

8.4. Comparaison de lexiques . . . . . . . . . . . . . . . . . . . . . . . . . .2798.5. Identification des verbes défectifs . . . . . . . . . . . . . . . .. . . . . . 2828.6. Dictionnaire de rimes . . . . . . . . . . . . . . . . . . . . . . . . . . . .2858.7. Enumération des instances d’une construction syntagmatique . . . . . . 2878.8. Identification des néologismes dans un texte étiqueté .. . . . . . . . . . 2898.9. Déterminer la catégorie d’une forme inconnue (word guessing) . . . . . 291

8.9.1. Version simple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2938.9.2. Version élaborée . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295

8.10. Fléchir des lemmes inconnus . . . . . . . . . . . . . . . . . . . . . .. 2978.11. Morphologie dérivationnelle . . . . . . . . . . . . . . . . . . . .. . . . 302

8.11.1. Concaténation et substitution . . . . . . . . . . . . . . . . .. . . 3038.11.2. Apprendre et appliquer des schémas dérivationnels. . . . . . . . 306

Chapitre 9. Manipulation de données au format XML . . . . . . . . . . . . 315

9.1. Principes généraux de XML . . . . . . . . . . . . . . . . . . . . . . . . .3159.1.1. Concepts et structure d’un document XML . . . . . . . . . . .. . 3169.1.2. Exemples de données en XML . . . . . . . . . . . . . . . . . . . . 3229.1.3. Traitements spécifiques nécessaires . . . . . . . . . . . . .. . . . 3259.1.4. Modules Perl disponibles . . . . . . . . . . . . . . . . . . . . . . .326

9.2. Analyse d’un fichier XML . . . . . . . . . . . . . . . . . . . . . . . . . . 3279.2.1. Approche minimaliste :XML::Simple . . . . . . . . . . . . . . 3289.2.2. Approche par flux (à la SAX) :XML::Parser . . . . . . . . . . 3329.2.3. Approche par construction d’arbre (à la DOM) :XML::DOM . . 339

9.3. Production de données au format XML . . . . . . . . . . . . . . . . .. 3429.3.1. Création de fichiers XML . . . . . . . . . . . . . . . . . . . . . . . 3439.3.2. Modification d’un fichier XML . . . . . . . . . . . . . . . . . . . . 347

9.4. Autres techniques et concepts . . . . . . . . . . . . . . . . . . . . .. . . 3519.4.1. Remarque sur le codage des caractères . . . . . . . . . . . . .. . . 3529.4.2. Modèles de documents et validation . . . . . . . . . . . . . . .. . 3529.4.3. Langages de requêtes en XML . . . . . . . . . . . . . . . . . . . . 3539.4.4. Transformation de documents . . . . . . . . . . . . . . . . . . . .. 353

Page 8: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

16 Perl pour les linguistes

Chapitre 10. Exploitation linguistique du Web . . . . . . . . . . . . . . . . . 355

10.1. Principes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35510.1.1. Organisation du Web . . . . . . . . . . . . . . . . . . . . . . . . . 35510.1.2. Structure générale d’une page HTML . . . . . . . . . . . . . .. 35710.1.3. Du HTML au texte brut . . . . . . . . . . . . . . . . . . . . . . . 36010.1.4. Pages Web et codage des caractères . . . . . . . . . . . . . . .. . 36110.1.5. Connexion à Internet . . . . . . . . . . . . . . . . . . . . . . . . . 362

10.2. Récupération et nettoyage d’une page Web . . . . . . . . . . .. . . . . 36310.2.1. Récupération du code HTML d’une page Web . . . . . . . . . .36310.2.2. Récupération du contenu textuel d’une page Web . . . .. . . . . 36510.2.3. Récupération récursive d’un site Web . . . . . . . . . . . .. . . . 369

10.3. Interrogation d’un moteur de recherche . . . . . . . . . . . .. . . . . . 37010.3.1. Syntaxe des requêtes . . . . . . . . . . . . . . . . . . . . . . . . . 37210.3.2. Remarques sur les résultats des moteurs . . . . . . . . . .. . . . 37310.3.3. Interrogation automatique de Yahoo :Yahoo Web Search Services. . . . . . . . . . . . . . . . . . . . . . . . . . 37410.3.4. Interrogation automatique deLive Search: Live Search API. . . 38110.3.5. Remarques sur l’interrogation automatique des moteursde recherche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385

10.4. Exemples d’utilisations complexes . . . . . . . . . . . . . . .. . . . . 38610.4.1. Problèmes techniques à traiter . . . . . . . . . . . . . . . . .. . . 38610.4.2. Calcul du nombre de documents indexés pour une listede mots . 38710.4.3. Extraction des contextes des termes de la requête . .. . . . . . . 389

Annexe 1. Préparation des données. . . . . . . . . . . . . . . . . . . . . . . . 395

A1.1. Conversion des retours à la ligne . . . . . . . . . . . . . . . . . .. . . 395A1.2. Segmentation en mots . . . . . . . . . . . . . . . . . . . . . . . . . . . 396

A1.2.1. Version simple . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397A1.2.2. Segmentation avec des exceptions . . . . . . . . . . . . . . .. . 399

A1.3. Suppression des entêtes de fichier du corpus de l’ABU . .. . . . . . 405A1.4. Désambiguïsation de la lemmatisation duTreeTagger . . . . . . . . . 406A1.5. Application d’un traitement à un ensemble de fichiers .. . . . . . . . 410

A1.5.1. Suppression des entêtes ABU dans un ensemble de fichiers . . . 411A1.5.2. Catégorisation d’un ensemble de fichiers . . . . . . . . .. . . . 412

Annexe 2. Codage des caractères. . . . . . . . . . . . . . . . . . . . . . . . . 415

A2.1. Généralités . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415A2.1.1. Rapide historique du codage des caractères . . . . . . .. . . . . 415A2.1.2. Polices de caractères . . . . . . . . . . . . . . . . . . . . . . . . .417A2.1.3. Conséquences pour le traitement linguistique . . . .. . . . . . . 418

A2.2. Principaux codages utilisés . . . . . . . . . . . . . . . . . . . . .. . . 419A2.2.1.ASCII . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419

Page 9: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Table des matières 17

A2.2.2.Latin1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419A2.2.3.Latin9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420A2.2.4.CP1252 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421A2.2.5.CP850 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421A2.2.6.MacRoman . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422A2.2.7.Unicode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422A2.2.8. Codage enASCIIdes caractères non standards . . . . . . . . . . 425

A2.3. Liens entre codage et système d’exploitation . . . . . . .. . . . . . . 426A2.3.1. Windows (français) . . . . . . . . . . . . . . . . . . . . . . . . . 426A2.3.2. Unix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427A2.3.3. MacOS X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428

A2.4. D’un code à l’autre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428A2.4.1. Diagnostics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428A2.4.2. Incompatibilités entre les codages . . . . . . . . . . . . .. . . . 430A2.4.3. Outils de recodage . . . . . . . . . . . . . . . . . . . . . . . . . . 431

A2.5. Gestion des codages en Perl . . . . . . . . . . . . . . . . . . . . . . .. 432A2.5.1. Comportement par défaut : le codeLatin1 . . . . . . . . . . . . . 433A2.5.2. Notation des autres caractères dans le code Perl :\x#### . 433A2.5.3. Codage des données d’entrée et de sortie :la fonctionbinmode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 434A2.5.4. Exemples complets . . . . . . . . . . . . . . . . . . . . . . . . . . 436A2.5.5. Recodage interne en Perl : le moduleEncode . . . . . . . . . . 438

A2.6. Problèmes fréquents . . . . . . . . . . . . . . . . . . . . . . . . . . . .439A2.6.1. Sous Windows, la sortie d’un programme dans un terminaln’affiche pas correctement les caractères accentués . . . . . .. . . . . . 439A2.6.2. L’exécution d’un programme donne le message d’erreur :Wide character in print.... . . . . . . . . . . . . . . . . . . . . . . . . . . 439A2.6.3. Sous Unix, l’utilisation de données provenant de Windows posedes problèmes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439A2.6.4. Le tri lexicographique ne se fait pas correctementpour les lettres accentuées . . . . . . . . . . . . . . . . . . . . . . . . . . 441A2.6.5. Sous Unix, comment travailler en environnement Unicode ? . . 442

A2.7. Références des principaux codages . . . . . . . . . . . . . . . .. . . . 443A2.7.1. Liste des caractères non affichables . . . . . . . . . . . . .. . . 443A2.7.2. Tables des principaux caractères latins à travers les codagesles plus fréquents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445

Annexe 3. Localisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 457

A3.1. Généralités . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 457A3.2. Les paramètreslocales. . . . . . . . . . . . . . . . . . . . . . . . . . . 458

A3.2.1. Langage de description deslocales. . . . . . . . . . . . . . . . . 458A3.2.2. Paramètres localisables . . . . . . . . . . . . . . . . . . . . . .. 460

A3.3. Impact des locales sur le traitement linguistique . . .. . . . . . . . . 461

Page 10: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

18 Perl pour les linguistes

A3.3.1. Principaux problèmes rencontrés . . . . . . . . . . . . . . .. . . 461A3.3.2. Sous un système Unix . . . . . . . . . . . . . . . . . . . . . . . . 461A3.3.3. Sous Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462A3.3.4. En Perl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462

A3.4. Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465

Annexe 4. Structures de données complexes et références. . . . . . . . . . 467

A4.1. Principes et cas d’utilisation . . . . . . . . . . . . . . . . . . .. . . . . 467A4.2. Références . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 468

A4.2.1. Création d’une référence . . . . . . . . . . . . . . . . . . . . . .469A4.2.2. Référence à un tableau . . . . . . . . . . . . . . . . . . . . . . . . 469A4.2.3. Référence à un hachage . . . . . . . . . . . . . . . . . . . . . . . 470

A4.3. Manipulation de structures complexes . . . . . . . . . . . . .. . . . . 471A4.3.1. Exemple de structure complexe : hachage de tableaux. . . . . . 471A4.3.2. Structures complexes hétérogènes . . . . . . . . . . . . . .. . . 473

A4.4. Notions connexes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475A4.4.1. Passage de paramètres à une fonction . . . . . . . . . . . . .. . 475A4.4.2. Références à des fonctions . . . . . . . . . . . . . . . . . . . . .476A4.4.3. Références à des descripteurs de fichiers . . . . . . . . .. . . . 477A4.4.4. Programmation orientée objet en Perl . . . . . . . . . . . .. . . 477

A4.5. Pour en savoir plus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 478

Annexe 5. Référence des principales notions de Perl. . . . . . . . . . . . . . 479

A5.1. Syntaxe générale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479A5.1.1. Structure d’un programme . . . . . . . . . . . . . . . . . . . . . 479A5.1.2. Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479A5.1.3. Affectation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 480A5.1.4. Entrées – Sorties . . . . . . . . . . . . . . . . . . . . . . . . . . . 480A5.1.5. Notation des caractères spéciaux . . . . . . . . . . . . . . .. . . 481A5.1.6. Conditionnelles . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481A5.1.7. Boucles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481

A5.2. Opérateurs fondamentaux . . . . . . . . . . . . . . . . . . . . . . . .. 482A5.2.1. Opérations sur les chaînes . . . . . . . . . . . . . . . . . . . . .. 482A5.2.2. Opérations sur les valeurs numériques . . . . . . . . . . .. . . . 483A5.2.3. Connecteurs logiques . . . . . . . . . . . . . . . . . . . . . . . . 483

A5.3. Tableaux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483A5.3.1. Notation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483A5.3.2. Manipulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484A5.3.3. Tri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484

A5.4. Hachages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485A5.4.1. Notation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485A5.4.2. Utilisation et affichage . . . . . . . . . . . . . . . . . . . . . . .. 485

A5.5. Fichiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 486

Page 11: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Table des matières 19

A5.5.1. Lecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 486A5.5.2. Ecriture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 486A5.5.3. Répertoires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 486

A5.6. Fonctions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487A5.7. Variables spéciales . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 487A5.8. Syntaxe des expressions régulières . . . . . . . . . . . . . . .. . . . . 487

A5.8.1. Liste des métacaractères . . . . . . . . . . . . . . . . . . . . . .487A5.8.2. Liste des notations . . . . . . . . . . . . . . . . . . . . . . . . . . 487A5.8.3. Rappel de la syntaxe Perl . . . . . . . . . . . . . . . . . . . . . . 488A5.8.4. Fonctions dédiées . . . . . . . . . . . . . . . . . . . . . . . . . . 489

Bibliographie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 491

Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493

Page 12: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

20

Page 13: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

L ISTE DES PROGRAMMES

3.1 flex-nom-masc.plPremier programme Perl : flexion d’un nom masculin . . . . . . . . .. . . . 1143.2 flex-nom-masc2.plVariante simplifiée deflex-nom-masc.pl: flexion d’un nom masculin . . . . 1233.3 flex-nom-mf.plExemple d’utilisation des conditionnelles : gestion du genrepour la flexion des noms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1243.4 flex-nom-mf2.plVersion simplifiée deflex-nom-mf.plutilisantelsif . . . . . . . . . . . . . . 1273.5 flex-nom-invar.plExemple d’utilisation des connecteurs logiques : gestion de quelques nomsinvariables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1293.6 flex-verb.plExemple d’utilisation des tableaux : la flexion des verbes . .. . . . . . . . . 1323.7 flex-nom-irreg.plExemple d’utilisation des hachages : le traitement des pluriels défectifs . . 1353.8 flex-liste-noms-masc1.plExemple d’utilisation des boucleswhile : la flexion d’une liste de nomsmasculins saisis par l’utilisateur . . . . . . . . . . . . . . . . . . . .. . . . . 1383.9 flex-liste-noms-masc2.plExemple d’utilisation des boucleswhile : flexions d’une liste de nomscontenue dans un fichier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1403.10 flex-verb2.plExemple d’utilisation des boucles : flexion d’un verbe . . . . .. . . . . . . 1433.11 flex-verb3.plExemple d’utilisation des bouclesforeach : flexion d’un verbe . . . . . . . 1453.12 flex-nom-invar-fichier.plExemple d’utilisation d’un fichier en lecture : flexion des nomsavec prise en compte d’une liste de noms invariables . . . . . . .. . . . . . 149

21

Page 14: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

22 Perl pour les linguistes

3.13 flex-verbe-fichier.plExemple d’utilisation de fichiers en écriture : flexion d’un verbeau présent et à l’imparfait . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 1523.14 flex-nom-masc-argument.plExemple d’utilisation d’arguments : flexion d’un nom masculin singulier . 1553.15 flex-nom-fonction.plExemple d’utilisation d’une fonction : flexion d’un nom . . . .. . . . . . . 1574.1 termine-s.plTest d’une terminaison ens par expression régulière . . . . . . . . . . . . . 1734.2 extraire-s.plTest d’une terminaison ens et extraction de sous-chaîne . . . . . . . . . . . 1804.3 radical-able.plExtraction du radical d’un adjectif en-able . . . . . . . . . . . . . . . . . . 1814.4 extraction-mots.plExtraction des mots d’une ligne de texte . . . . . . . . . . . . . . . . .. . . 1835.1 recherche-exacte-simple.plRecherche d’un mot exact dans un fichier de texte segmentéou un lexique simple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1925.2 recherche-exacte-liste.plRecherche d’une liste de mots dans un fichier de texte segmentéou un lexique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1945.3 recherche-expreg-simple.plRecherche par expression régulière dans une liste de mots . .. . . . . . . . 1975.4 recherche-expreg-tri.plRecherche par expression régulière dans une liste de mots,avec tri des résultats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1995.5 recherche-lemme.plRecherche par lemme dans un texte étiqueté . . . . . . . . . . . . . . .. . . 2025.6 adjectifs-able.plExtraction des adjectifs en-abled’un texte étiqueté . . . . . . . . . . . . . . 2055.7 recherche-categorie-lemme.plRecherche dans un texte étiqueté sur la catégorie et le lemme. . . . . . . . 2075.8 adjectifs-able-non-prefixes.plRecherche dans un texte étiqueté des adjectifs en-ablenon préfixéspardé-ni in- . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2085.9 recherche-able-texte-brut.plRecherche des mots finissant parableouablesdans un texte brut . . . . . . 2105.10 recherche-det-X.plRecherche en texte brut d’une séquence composée d’un article définisuivi d’un mot quelconque . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2125.11 recherche-X-de-X.plRecherche de séquences du typeX de X et X de Det X dans un texte brut . 215

Page 15: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Liste des programmes 23

5.12 recherche-N-de-N.plRecherche de séquencesN de Ndans un texte étiqueté . . . . . . . . . . . . 2175.13 automate-N-de-N.plRecherche de séquencesN de (DET) N de (DET) N...par automateà états finis dans un texte étiqueté . . . . . . . . . . . . . . . . . . . . . .. . 2215.14 recherche-lemme-fichiers.plRecherche d’un lemme dans un ensemble de textes étiquetés . .. . . . . . 2256.1 frequences-formes.plTable de fréquence des formes triées par ordre de fréquence décroissante,puis par ordre lexicographique . . . . . . . . . . . . . . . . . . . . . . . .. . 2316.2 frequences-formes-categories.plTable de fréquences des couples forme/catégorie triée par ordrede fréquence décroissante, puis par ordre lexicographiquede la forme,puis par ordre lexicographique de l’étiquette . . . . . . . . . . .. . . . . . . 2346.3 rang-lemme.plRang des lemmes triés par fréquence décroissante . . . . . . . . .. . . . . . 2376.4 cooccurrences-formes.plCooccurrents des formes simples d’un texte étiqueté . . . . . .. . . . . . . 2416.5 cooccurrences-lemmes-filtre.plCooccurrents filtrés des lemmes d’un texte étiqueté . . . . . . .. . . . . . . 2466.6 infomutuelle.plCooccurrents des lemmes d’un texte étiqueté triéspar information mutuelle . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2507.1 concord-brut-simple.plConcordances simples sur texte brut . . . . . . . . . . . . . . . . . . . .. . 2577.2 concord-brut-expreg.plConcordances par expressions régulières sur texte brut . . .. . . . . . . . . 2658.1 noms-ite.plExtraction des noms en-etéet -ité du lexiqueMorphalou . . . . . . . . . . 2718.2 caracterisation-lexique.plCaractérisation quantitative d’un lexique . . . . . . . . . . . . .. . . . . . . 2738.3 fusion-lexiques.plFusion de deux lexiques au même format . . . . . . . . . . . . . . . . . . .. 2768.4 fusion-tri-lexiques.plFusion de deux lexiques au format GRACE puis tri des entréesdu lexique résultat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2778.5 comparaison-lexiques-formes.plComparaison de deux lexiques au format GRACE relativement aux formes,aux catégories et aux lemmes . . . . . . . . . . . . . . . . . . . . . . . . . . 2808.6 verbes-defectifs.plRepérage des verbes défectifs dans un lexique au format GRACE . . . . . . 2838.7 dictionnaire-rimes.plConstruction d’un dictionnaire de rimes à partir deLexique.org. . . . . . . 286

Page 16: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

24 Perl pour les linguistes

8.8 instances-construction.plEnumération des instances d’une construction syntagmatique . . . . . . . . 2888.9 neologismes.plDétection des néologismes contenus dans un texte catégorisé . . . . . . . . 2908.10 determination-categorie.plPrédiction déterministe de la catégorie d’une liste de motsinconnus . . . . 2938.11 determination-categories-multi.plPrédiction non déterministe de la catégorie d’une liste de mots inconnus . . 2958.12 flexion-inconnu.plFlexion d’un lemme inconnu . . . . . . . . . . . . . . . . . . . . . . . . . . . 2998.13 prefixation-in.plPréfixation enin- des formes lues sur l’entrée standard . . . . . . . . . . . . 3048.14 suffixation-age.plSuffixation en-ageà partir de formes au participe présent . . . . . . . . . . 3058.15 apprentissage-suffixation.plApprentissage de schémas de suffixation . . . . . . . . . . . . . . . . .. . . 3088.16 suffixation.plSuffixation des mots bases . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3129.1 analyse-XML-simple.plAnalyse d’un texte étiqueté au format XMLvia le moduleXML::Simple . . . . . . . . . . . . . . . . . . . . . . . . . . 3309.2 extraction-noms-morphalou.plExtraction des formes nominales du lexiqueMorphalou . . . . . . . . . . . 3339.3 extraction-Ozkan-flux.plExtraction du texte d’un dialogue du corpus Ozkanvia un traitement par flux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3379.4 expressions-Ozkan-DOM.plExtraction des expressions référentielles et de leurs caractéristiquesd’un dialogue du corpus Ozkanvia le moduleXML::DOM . . . . . . . . . . 3409.5 conversion-tag-XML.plConversion d’un fichier de texte étiqueté en format XML . . . . .. . . . . 3439.6 modification-Ozkan.plModification d’un document XML du corpus Ozkan :suppression des élémentskinesic_action et ajout de tracesde la modification dans l’entête . . . . . . . . . . . . . . . . . . . . . . . .. 34810.1 URL-HTML.plRécupération du code HTML complet d’une page Web . . . . . . . . . .. . 36410.2 URL-texte.plRécupération d’une page Web et transformation en texte brut. . . . . . . . 36610.3 recherche-Yahoo.plInterrogation de Yahoovia Yahoo Web Search Services. . . . . . . . . . . . 37510.4 recherche-Live.plInterrogation de Live Searchvia Live Search API. . . . . . . . . . . . . . . 382

Page 17: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Liste des programmes 25

10.5 frequences-Yahoo.plCalcul du nombre de documents indexés par Yahoo pour une liste de mots . 38710.6 contextes-Yahoo.plExtraction des contextes des résultats de Yahoo pour une requête donnée . . 389A1.1 conversion-fins-ligne.plConversion des fins de ligne Windows sous Unix . . . . . . . . . . . . .. . 396A1.2 segmentation-mots-simple.plSegmentation grossière d’un texte en mots et signes de ponctuation . . . . . 397A1.3 segmentation-mots-exceptions.plSegmentation en mots fine qui respecte une liste d’exceptions définiepar l’utilisateur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .400A1.4 suppression-entete-ABU.plSuppression des entêtes des fichiers du corpus de l’ABU . . . . .. . . . . . 405A1.5 desambiguisation-lemmatisation.plDésambiguïsation de la lemmatisation duTreeTagger . . . . . . . . . . . . 408A1.6 suppression-entetes-ABU-repertoire.plSuppression des entêtes de tous les fichiers ABU qui se trouventdans un répertoire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411A1.7 categorisation-repertoire.plCatégorisation des fichiers qui se trouvent dans un répertoire . . . . . . . . 413A2.1 extrait-oe.plExtraction de ligatures codées enLatin9sous Windows avec sortieenCP1252 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436A2.2 extrait-oe-CP850.plExtraction de ligatures codées enLatin9sous Windows avec sortieenCP850. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437

Page 18: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

26

Page 19: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

INTRODUCTION

Cet ouvrage de programmation en Perl s’adresse aux linguistes et à tous ceux quiont besoin d’explorer et d’exploiter des données langagières volumineuses. Il a pourobjectif de leur proposer des méthodes et des techniques informatisées permettant deréaliser ces tâches avec plus d’efficacité, plus de systématicité et sur des quantités dedonnées plus grandes. Ils y apprendront les règles d’utilisation et de construction deprogrammes informatiques dédiés à la manipulation de textes, de lexiques, et de touteressource langagière qu’ils souhaitent utiliser dans le cadre de leur activité scienti-fique.

Ce livre est accessible à tous, y compris à ceux qui n’ont aucune formation eninformatique ou en programmation. Le lecteur y est guidé pasà pas, notamment dansla première partie consacrée aux aspects techniques de base.

A quel linguiste s’adresse cet ouvrage ?

Ce livre est destiné au linguiste qui souhaite travailler sur des données avec unordinateur plutôt que manuellement. Le linguiste visé ici est avant tout celui qui estdéjà convaincu que l’étude du langage nécessite un recours àdes attestations ou à desressources extensives. Il trouvera dans cet ouvrage un tourd’horizon des ressourcesdisponibles, des traitements fondamentaux qui permettentde les manipuler, et destechniques informatiques de base qui en facilitent l’exploitation.

Le livre peut également être utile aux linguistes qui s’intéressent aux aspects plusformels de l’étude du langage. Les spécialistes de linguistique formelle et de statis-tique lexicale ou textuelle ont en effet besoin d’alimenterleurs modèles avec des don-nées et de les confronter à ces dernières. L’ouvrage proposedes techniques directe-ment utilisables pour gérer ces données, voire automatisercertains calculs complexes.

Les informaticiens linguistes qui travaillent sur le traitement automatique deslangues et en ingénierie linguistique peuvent pour leur part être intéressés par les

27

Page 20: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

28 Perl pour les linguistes

avantages que possède Perl sur d’autres langages de programmation pour la mani-pulation des données langagières. Le livre présente notamment les techniques qui fontla spécificité de Perl et qui permettent de développer très rapidement des prototypesd’applications, mais aussi d’écrire ces petits traitements de données qu’un logicielplus complexe nécessite bien souvent en amont.

Plus généralement, les linguistes peuvent découvrir dans ce livre les différentesfaçons d’envisager un travail sur des données, la richesse des ressources et des tech-niques disponibles, et tout ce que peut leur apporter l’utilisation des outils informa-tiques.

Pourquoi apprendre la programmation quand on est linguiste?

Il peut paraître superflu pour un linguiste d’acquérir une compétence aussi pointueque la connaissance d’un langage de programmation. Cette activité, réputée aride, dé-voreuse de temps et génératrice de frustrations, paraît en effet faire double emploi avecl’utilisation des nombreux outils informatiques disponibles qui permettent d’analyser,de fouiller, de calculer et de produire des données langagières.

La première réponse est simple : l’étendue des besoins est telle qu’aucun outilpréconçu ne peut prétendre y répondre. Nombre d’études linguistiques font de faitsouvent appel à plusieurs outils (Benoît Habert parle d’instrumentsdans [HAB 05]),qu’il est alors nécessaire de maîtriser et de savoir articuler pour arriver à ses fins. Alorsque dans bien des cas, un programme conçu spécifiquement peutsimplifier le travail.De même, l’utilisation de deux applications préconçues nécessite systématiquementd’adapter les productions de l’une aux exigences de l’autre. Ceci entraîne le dévelop-pement de ces petits programmes rapidement écrits et encoreplus vite oubliés que lejargon nomme affectueusementmoulinettes.

La deuxième réponse concerne les données elles-mêmes, et lamultiplicité de leursformats (c’est-à-dire des types d’informations qu’ils contiennent et de leurs organi-sations) que la disponibilitévia le Web ne fait qu’accroître. Il devient rapidementnécessaire d’adapter à chaque nouveau corpus ou nouveau texte au moins une partied’un traitement automatisé. Il faut, en plus d’une connaissance des différents formatset des problèmes liés à chacun, disposer de moyens rapides des’y adapter.

La troisième réponse ne se formule pas en termes d’utilité directe, mais revendiqueque l’apprentissage de la programmation est en soi une ouverture sur de nouvelles fa-çons d’aborder et de résoudre un problème, qui peut se révéler fructueuse dans l’étudedu langage.

Page 21: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Introduction 29

Pourquoi choisir le langage Perl ?

Le choix d’un langage de programmation a toujours été une opération délicate quidoit être guidée par les besoins de l’utilisateur.

Le linguiste a tout d’abord besoin de manipuler des données textuelles. Ces traite-ments sont assez ciblés : il s’agit essentiellement d’exploiter des fichiers de données,d’en extraire des séquences de caractères, de les manipuler, de les comparer, de lestrier, de les compter, etc. Il faut donc disposer de méthodesperformantes et efficacespermettant d’aborder facilement différents types de situations, et de gérer des volumesde données parfois très importants.

Dans de nombreux cas, par exemple lorsqu’il s’agit d’adapter un traitement à untype de données spécifique, les opérations effectuées par unprogramme ne sont exé-cutées qu’une fois ou deux : il est alors important de pouvoirréaliser rapidement unprogramme donné, même si celui-ci pourrait être amélioré, pourvu qu’il réponde auxbesoins exprimés.

Enfin, le type de programmation dont un linguiste a besoin doit être économe enmoyens techniques et ne pas nécessiter un environnement informatique sophistiqué :un langage dont les outils de développements sont gratuits et disponibles sous tous lestypes de plate-forme aura ici un avantage.

Ces trois exigences font de Perl le candidat retenu : initialement conçu pour lagestion de la documentation électronique, il dispose de toutes les fonctionnalités né-cessaires à la manipulation de données linguistiques, notamment grâce à la puissancede ses expressions régulières (voir chapitre 4). Langage descript (voir chapitre 3), ilne nécessite pas de phase de compilation préalable et dispose de plus d’une syntaxetrès souple et concise. Proposé gratuitement et pour tous les systèmes d’exploitation(voir chapitre 2), il ne nécessite aucun investissement en termes d’équipement ou delogiciels autre qu’un ordinateur PC ou Mac.

Que va-t-on apprendre à faire avec Perl ?

Si le champ d’application des techniques présentées dans cet ouvrage se veut leplus large possible, nous nous concentrerons sur des opérations fondamentales.

Les premières manipulations concernent des opérations de flexion automatique,de recherche dans les textes de mots ou de séquences de mots, et de calculs de fré-quence. Toutes ces opérations permettent, en réappliquantleurs mécanismes, d’abor-der nombre d’études d’un corpus de textes écrits comme l’analyse du vocabulaire oul’étude de certaines constructions syntaxiques. L’outil informatique a alors commerôle principal de permettre un examen rapide et exhaustif d’un ensemble de phéno-mènes linguistiques.

Page 22: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

30 Perl pour les linguistes

L’accent est également mis sur les manipulations de ressources lexicales, que cesoit pour des approches morphologiques comme l’étude d’un suffixe, ou pour l’acqui-sition de ressources (comme une liste de néologismes) à partir d’un corpus.

Nous aborderons à plusieurs reprises la prise en compte de différents formats dedonnées, notamment pour tirer partie (et produire) des textes annotés, et aborder l’uti-lisation du Web comme source de données.

Tous les exemples développés portent sur le français, mais ils sont applicablessans modifications majeures à d’autres langues (les limitesétant ici la disponibilitédes ressources et les difficultés techniques liées à la manipulation d’écritures non al-phabétiques).

Des applications plus complexes (pouvant se rapprocher destechniques plus so-phistiquées relevant du traitement automatique des langues) peuvent tout à fait êtreenvisagées sur la base des savoir-faire fondamentaux présentés ici.

Plan de l’ouvrage

Perl pour les linguistesest composé de 10 chapitres et d’une série d’annexes.

Les quatre premiers chapitres ont pour but d’accompagner lelecteur dans sa dé-couverte des notions fondamentales sur lesquelles s’appuient les traitements completsprésentés par la suite. Ils peuvent être lus dans l’ordre parun utilisateur débutant, ouêtre abordés ponctuellement par la suite à l’occasion de renvois.

Le chapitre 1 (Données) effectue un tour d’horizon des différents matériaux mani-pulés par les programmes et techniques. Le lecteur y trouvera à la fois une présentationdétaillée des principaux concepts liés aux textes numériques, ainsi qu’une liste des dif-férentes sources de données disponibles et des traitementsautomatiques préparatoiresqui peuvent s’y appliquer.

Le chapitre 2 (Environnement de travail et notions de système) détaille les pro-cédures techniques nécessaires à la mise en place de l’environnement de travail, etexplique les opérations minimales permettant à l’utilisateur d’exécuter et de dévelop-per des programmes en Perl.

Le chapitre 3 (Bases de Perl) présente, à travers une série de programmes simples,les éléments fondamentaux de ce langage de programmation.

Le chapitre 4 (Expressions régulières) aborde un des outils les plus puissants pourla manipulation automatique de données textuelles : les expressions régulières. Leformalisme en est détaillé, ainsi que son utilisation dans un programme Perl.

Page 23: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Introduction 31

Les six chapitres suivants sont consacrés chacun à un type demanipulation oude données particulières. Chacun d’eux présente, à traversune série de programmescomplets de complexité croissante, des traitements directement utilisables, tout en lesdétaillant suffisamment pour permettre leur extension et leur adaptation à de nouveauxbesoins.

Le chapitre 5 (Recherche d’unités linguistiques) traite des procédures automa-tiques de repérage et d’extraction de différents types d’unités dans des textes numé-riques (mots ou suites de mots).

Le chapitre 6 (Calculs de fréquences) aborde l’obtention d’informations synthé-tiques sur la répartition des unités linguistiques dans lestextes. Les principes de lastatistique lexicale y sont abordés.

Le chapitre 7 (Concordances) se concentre sur la construction et la présentationde lignes de contextes issues d’un texte permettant l’étudesystématique des unitéslexicales.

Le chapitre 8 (Traitements lexicaux) couvre l’ensemble des techniques utilisablessur la base de listes de mots, et notamment différentes méthodes de traitement mor-phologique.

Le chapitre 9 (Manipulation de données au format XML) présente les principesfondamentaux de cette norme de description des documents, et les différentes tech-niques permettant de manipuler ce type de format de données de plus en plus répandu.

Le chapitre 10 (Exploitation linguistique du Web) est consacré à l’utilisation duWeb comme source de données linguistiques et comme corpus d’étude.

Enfin, une série d’annexes permet de détailler certains aspects techniques plus se-condaires. Des renvois systématiques vers cette partie sont présents dans les chapitresprécédents pour permettre l’approfondissement de certaines questions.

L’annexe A1 (Préparation des données) présente les programmes utilisés pour pré-parer des données brutes, permettant à l’utilisateur d’étendre les matériaux sur lesquelsil peut appliquer les traitements présentés dans le reste del’ouvrage.

L’annexe A2 (Codage des caractères) aborde les délicates questions du codagenumérique des caractères, et contient notamment un ensemble de solutions à appliqueren cas de problèmes liés à cette notion, ainsi que plusieurs tables de référence sur lesprincipaux caractères.

L’annexe A3 (Localisation) présente les principes techniques de l’adaptation d’untraitement linguistique à une autre langue que celle prévueinitialement. En plus des

Page 24: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

32 Perl pour les linguistes

opérations techniques permettant de configurer correctement un programme ou un sys-tème d’exploitation, cette annexe est recommandée aux lecteurs souhaitant appliquerles techniques de cet ouvrage à d’autres langues que le français.

L’annexe A4 (Structures de données complexes et références) aborde certains as-pects plus pointus de la programmation en Perl, et notammentles structures complexeset la programmation orientée objet.

L’annexe A5 (Référence des principales notions de Perl) contient une liste récapi-tulative des notations en Perl, classées par thème, et se veut d’un accès rapide pour unutilisateur souhaitant simplement se remémorer un détail technique.

Enfin, un index complet est disponible en fin d’ouvrage, ainsiqu’une bibliographierenvoyant à la fois vers des ouvrages techniques et vers des travaux en linguistique.

Conventions typographiques

Les conventions suivantes sont appliquées tout au long de l’ouvrage pour la nota-tion des différentes notions techniques :

– les noms de fichiers et de programmes (programme.pl), ainsi que les commandessystèmes (cd) sont en caractères inclinés ;

– les noms de modules Perl (XML::Simple ), les noms de variables ($chaine ),les opérateurs Perl (==) et les lignes de commandes à saisir sont en caractères à chassefixe ;

– les chaînes de caractères (lapin) sont en italique ;

– les noms de fonctions Perl (print ) sont en gras ;

– les expressions régulières sont en chasse fixe et placées entre barres obliques(/comme ceci/ ).

Mise en route et utilisation de l’ouvrage

La lecture de cet ouvrage doit être perçue comme un accompagnement à une dé-couverte pratique des différentes méthodes présentées. L’ensemble des programmeset des exemples de données qu’ils permettent de manipuler sont mis à disposition surle site Web d’accompagnement :

http://perl.linguistes.free.fr/

Nous invitons donc sans plus attendre le lecteur à se rendre sur ce site pour ytélécharger l’archive correspondant au système d’exploitation dont il dispose. Le cha-pitre 2 détaille les différentes étapes complémentaires afin d’obtenir un environnementde travail complet.

Page 25: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Introduction 33

Le lecteur néophyte en programmation est bien sûr invité à lire cet ouvrage dansl’ordre prévu.

Ceux qui souhaitent simplement résoudre un problème spécifique sans acquérirau préalable un savoir-faire en programmation peuvent se rendre directement au cha-pitre correspondant à la problématique qui les intéresse. Une liste des différents pro-grammes détaillés dans l’ouvrage est disponible en page 21.

Remerciements

Merci à Fiammetta Namer pour l’énergie qu’elle a insufflée dans le démarrage dece travail, et pour son enthousiasme dans nos nombreuses collaborations.

Merci aux membres de l’équipe de recherche CLLE-ERSS pour leurs relectures,commentaires et encouragements, et plus particulièrementà Didier Bourigault, GillesBoyé, Cécile Fabre, Edith Galy, Aurélie Picton et Franck Sajous.

Page 26: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

34

Page 27: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

CHAPITRE 1

Données

Ce livre s’adresse d’abord aux linguistes, et en particulier à ceux qui souhaitentenrichir la panoplie des méthodes et des outils qui sont à leur disposition. Il a pour ob-jectif de les aider à mener des recherches qui comportent l’observation de phénomèneslinguistiques dans des collections de données. Ces donnéessont essentiellement dedeux types :

– des productions langagières de toutes sortes comme des œuvres littéraires, de ladocumentation technique ou des transcriptions de dialogues oraux ;

– des œuvres et des ressources lexicographiques comme des dictionnaires numé-risés, des lexiques flexionnels ou des bases de données lexicales.

Les données que nous considérons sont représentées dans desdocuments ou desparties de documents matérialisés sur des supports électroniques, les seuls qui soientdirectement exploitables au moyen de programmes informatiques.

1.1. Exemples de données

Un premier exemple de ressource électronique est la liste demots du françaisdico(voir paragraphe 1.5.2.1), dont une copie est incluse dans l’environnement de travailfourni avec le présent ouvrage (voir chapitre 2). La figure 1.1 en contient un courtextrait qui présente les premières et les dernières lignes de cette liste.

Cette ressource se présente comme un texte que l’on peut lireet dont chaque lignecontient un mot du français. Les mots sont ordonnés lexicographiquement, c’est-à-direde la même manière que les entrées d’un dictionnaire.

35

Page 28: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

36 Perl pour les linguistes

aàabaissaabaissaientabaissaisabaissait[...]zouavezouaveszozoterzyeuterzygomatiquezygomatiques

Figure 1.1. Extrait de la liste de motsdico

Les utilisations de ce type de lexique sont diverses. On peutpar exemple s’en servirpour trouver des mots qui se terminent en-ion comme :

abdication ébullition narration sacralisationaberration éclosion natation salivationabjection édification nation salutationabjuration édition nationalisation sanctificationablation éducation naturalisation sanction

Figure 1.2. Mots du lexique du français qui se terminent en-ion

Un autre type de données largement utilisé dans les recherches en linguistiquesont les textes d’œuvres littéraires, d’articles de journaux, de manuels techniques,etc. L’ABU (Association des bibliophiles universels : voirparagraphe 1.5.1.4) met parexemple à la disposition du public une collection de textes divers qui contient notam-ment le recueil d’histoiresA se tordred’Alphonse Allais. Une copie de ce document setrouve dans le fichiertordre1.abude l’environnement de travail fourni avec l’ouvrage.En voici quelques fragments :

--- ATTENTION : CONSERVEZ CETTE LICENCE SI VOUS REDISTRIBUEZ CE FICHIER ---License ABU-=-=-=-=-=-Version 1.1, Aout 1999

Copyright (C) 1999 Association de Bibliophiles Universelshttp://abu.cnam.fr/[email protected]

La base de textes de l’Association des Bibliophiles Univers els (ABU)est une oeuvre de compilation, elle peut être copiée, diffus ée etmodifiée dans les conditions suivantes :

1. Toute copie à des fins privées, à des fins d’illustration d e l’enseignementou de recherche scientifique est autorisée.

[...]

----------------------- FIN DE LA LICENCE ABU ----------- ---------------------

Page 29: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Données 37

--- ATTENTION : CONSERVEZ CET EN-TETE SI VOUS REDISTRIBUEZ CE FICHIER ---<IDENT tordre><IDENT_AUTEURS allaisa><IDENT_COPISTES thiriets><ARCHIVE http://abu.cnam.fr/><VERSION 1><DROITS 0><TITRE A se tordre><GENRE prose><AUTEUR Allais, Alphonse><COPISTE Serge Thiriet><NOTESPROD></NOTESPROD>----------------------- FIN DE L’EN-TETE -------------- ------------------

------------------------- DEBUT DU FICHIER tordre1 ----- -------------------------

A SE TORDREHistoires chatnoiresquesAPHONSE ALLAIS(1891)

UN PHILOSOPHE

Je m’étais pris d’une profonde sympathie pour ce grand flemm ard de gabelou que mesemblait l’image même de la douane, non pas de la douane traca ssière desfrontières terriennes, mais de la bonne douane flâneuse et c ontemplative desfalaises et des grèves.Son nom était Pascal ; or, il aurait dû s’appeler Baptiste, ta nt il apportait dedouce quiétude à accomplir tous les actes de sa vie.Et c’était plaisir de le voir, les mains derrière le dos, traî ner lentement sestrois heures de faction sur les quais, de préférence ceux où n e s’amarraient quedes barques hors d’usage et des yachts désarmés.Aussitôt son service terminé, vite Pascal abandonnait son p antalon bleu et satunique verte pour enfiler une cotte de toile et une longue bl ouse à laquelle descoups de soleil sans nombre et des averses diluviennes (peut -être mêmeantédiluviennes) avaient donné ce ton spécial qu’on ne trou ve que sur le dos despêcheurs à la ligne. Car Pascal pêchait à la ligne, comme feu m onseigneur leprince de Ligne lui-même.[...]

------------------------- FIN DU FICHIER tordre1 ------- -------------------------

Figure 1.3. Extrait de la copie de l’ABU du recueil d’histoiresA se tordred’Alphonse Allais

Il s’agit ici d’un fichier detexte brutdépourvu de tout élément de mise en pagetypographique comme par exemple des changements de taille ou de polices de carac-tères. Ce fichier comporte essentiellement trois parties : 1) la licence ABU qui indiquele copyrightet rappelle les obligations des utilisateurs de cette ressource ; 2) une entêtequi présente diverses informations métatextuelles ; 3) le texte des histoires proprementdit. Les trois parties sont délimitées par des lignes de séparation qui indiquent la na-ture de l’objet textuel qui commence ou qui finit. Par exemple, la licence de l’ABUest située entre les lignes qui contiennentATTENTION : CONSERVEZ CETTE LI-CENCE SI VOUS REDISTRIBUEZ CE FICHIERet FIN DE LA LICENCE ABU. Lesinformations qui se trouvent dans la deuxième partie sont placées à l’intérieur de ba-lises, délimitées par des chevrons (comme<IDENT tordre>). L’absence de mise enpage apparaît clairement dans la dernière partie où les éléments du titre du livre et les

Page 30: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

38 Perl pour les linguistes

titres des histoires (par exemple,UN PHILOSOPHE) ne se distinguent des autres pa-ragraphes que par leur casse : ils sont entièrement en majuscules. La graphie erronéedu prénom de l’auteurAPHONSEprovient du fichier de l’ABU.

Les utilisations possibles de ce texte sont nombreuses. On peut par exemple enextraire le vocabulaire pour le comparer à celui d’œuvres plus classiques et y repérerdes mots rares ou familiers commegabelou. En se concentrant sur un mot particulier(commedouane), on peut en extraire le vocabulaire associé (notamment lesadjectifstracassière, flâneuse, contemplative). On peut également y repérer des structures syn-tagmatiques commeDEMONSTRATIF NOM1 de NOM2, et étudier les connotationspéjoratives du premier nom (comme iciflemmarddansce flemmard de gabelou).

1.2. Exemple d’utilisation de données pour des recherches en linguistique

Pour illustrer l’utilisation des ressources, considéronsle cas d’un linguiste qui sou-haite décrire la suffixation en-ion en français contemporain et en proposer une ana-lyse. Cette suffixation forme des noms essentiellement à partir de verbes (fédérer>fédération, générer> génération, transmettre> transmission, éclore> éclosion, pré-voir > prévision) mais également d’adjectifs commeinadéquat> inadéquation et denoms commenid > nidation. Pour être capable d’évaluer les résultats de son étude, cechercheur doit disposer d’un corpus de noms suffixés en-ion appartenant au lexiquefrançais contemporain. Cette collection de mots a deux finalités : 1) permettre l’es-timation de la couverture de la description et de la justessedes analyses ; 2) fournirdes données pour la description (identifier des séries et déterminer leur organisation)et la mise au point des analyses (identifier les paramètres etleur contribution). Pouratteindre ces deux objectifs, il faut donc que ce corpus constitue un fragment repré-sentatif du sous-lexique des noms suffixés en-ion. Il doit notamment avoir une taillesuffisante, contenir l’essentiel des mots en-ion que l’on rencontre couramment etillustrer les principaux modes de formation de ces noms.

Nous ne nous intéressons qu’aux méthodes qui permettent de constituer un telcorpus à partir de ressources informatisées et de l’exploiter au moyen de programmes.Ces ressources sont les lexiques électroniques et les textes. On peut ainsi profiter dufait que certains lexiques sont issus de dictionnaires de référence comme leTrésor dela Langue Française(TLF) et qu’ils peuvent être considérés comme ayant une bonnereprésentativité de la langue française (voir paragraphe 1.5.2.3). Une liste de nomsen -ion qui en est extraite hérite de cette qualité et de cette réputation. Cependant,le français décrit dans un dictionnaire comme leTLF est celui duXIX e siècle et dudébut duXX e. Ce n’est donc pas à proprement parler du français contemporain. Cettedifficulté peut être surmontée en ayant recours à des textes récents, par exemple lesarchives d’un quotidien commeLe Monde(voir paragraphe 1.5.1.10), qui sont mieuxadaptés à l’observation de cet état du français.

Page 31: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Données 39

La ressource à partir de laquelle le corpus sera constitué étant choisie, le linguistedoit identifier le ou les programmes à utiliser pour réalisercette collecte. En l’occur-rence, la liste des noms en-ion qui apparaissent dans ces textes peut être constituée aumoyen d’une variante du programme 5.6 (page 205) du chapitre5. Deux tâches préa-lables à la mise en œuvre de ce programme sur cette ressource doivent être réalisées :1) obtenir la ressource ; 2) l’adapter au format attendu par le programme.

1.3. Présentation du chapitre

La constitution d’un tel corpus ne peut être réalisée sans une connaissance suffi-sante des ressources disponibles (quelles archives utiliser et comment les obtenir ?),de leur nature (peut-on en extraire le texte et si oui comment?), de leur contenu (lesinformations recherchées y sont-elles présentes ?). C’està ces trois questions que cechapitre est consacré.

Le reste du chapitre se divise en quatre sections. La première (1.4) présente leformat texte, les formats de documents les plus courants et les outils qui permettentde les visualiser, les manipuler, et en extraire le contenu textuel. La section 1.5 estun inventaire non exhaustif de ressources textuelles et lexicales que l’on peut utiliserpour des recherches en linguistiques. La section 1.6 est consacrée au téléchargementde ressources disponibles sur le Web. La dernière section (1.7) est consacrée à la seg-mentation, la catégorisation et la lemmatisation des textes. Elle présente notammentle catégoriseurTreeTaggeret son jeu d’étiquettes.

Le présent chapitre et le suivant sont relativement interdépendants. Le premierprésente les données qui sont utilisées dans les exemples proposés dans le chapitresuivant. Réciproquement, le deuxième chapitre décrit les notions informatiques fon-damentales et l’environnement de travail dans lequel doivent être réalisées les diffé-rentes procédures et manipulations présentées dans ce chapitre-ci. Ces procédures sontproposées dans deux versions :

– au moyen d’outils disposant d’une interface graphique pour les lecteurs novicesen informatique ;

– au moyen de commandes en ligne (voir paragraphe 2.3.2) pourles lecteurs quisavent interagir avec leur système d’exploitation sans recourir à l’environnement gra-phique de ce dernier. Nous supposons que c’est le cas des utilisateurs de systèmes detype Unix, mais la plupart de ces commandes sont aussi disponibles sous Windows.

Dans tous les cas, nous donnons les adresses Web auxquelles ces outils et leur docu-mentation peuvent être obtenus.

La priorité est donnée dans ce livre au traitement du français. Le lecteur qui sou-haite travailler sur d’autres langues peut facilement récupérer sur le Web des res-sources similaires à celles qui sont présentées ici. Par ailleurs, nous ne considérons

Page 32: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

40 Perl pour les linguistes

ici que les documents écrits. Le traitement des données orales nécessite en effet l’uti-lisation d’outils spécifiques qui dépassent le cadre du présent ouvrage.

1.4. Formats de documents électroniques

Les documents électroniques sont des objets complexes qui peuvent se présenterdans différents formats : pages Web, documentsWord, images scannées, etc. Lesprogrammes Perl décrits dans cet ouvrage ne permettent pourleur part de manipulerque des données au format texte. Cette section est consacréeà ce format fondamentalet à la création de versions texte de documents qui ont un format original différent.

1.4.1. Le format texte

Un document en format texte (également appelétexte brut) est une représentationd’un document original qui ne contient plus que son texte, c’est-à-dire des séquencesdes caractères qui composent ses paragraphes. Dans ce format, les éléments de miseen page sont inexistants, ainsi que tous les objets qui ne sont pas des paragraphes detexte comme les figures, les formules ou les tableaux. Reprenons l’exemple du texteprécédent dans la figure 1.4.

A SE TORDREHistoires chatnoiresquesAPHONSE ALLAIS(1891)

UN PHILOSOPHE

Je m’étais pris d’une profonde sympathie pour ce grand flemm ard de gabelou que mesemblait l’image même de la douane, non pas de la douane traca ssière desfrontières terriennes, mais de la bonne douane flâneuse et c ontemplative desfalaises et des grèves.Son nom était Pascal ; or, il aurait dû s’appeler Baptiste, ta nt il apportait dedouce quiétude à accomplir tous les actes de sa vie.Et c’était plaisir de le voir, les mains derrière le dos, traî ner lentement sestrois heures de faction sur les quais, de préférence ceux où n e s’amarraient quedes barques hors d’usage et des yachts désarmés.Aussitôt son service terminé, vite Pascal abandonnait son p antalon bleu et satunique verte pour enfiler une cotte de toile et une longue bl ouse à laquelle descoups de soleil sans nombre et des averses diluviennes (peut -être mêmeantédiluviennes) avaient donné ce ton spécial qu’on ne trou ve que sur le dos despêcheurs à la ligne. Car Pascal pêchait à la ligne, comme feu m onseigneur leprince de Ligne lui-même.

Figure 1.4. Extrait du texte de la copie de l’ABU du recueil d’histoiresA setordred’Alphonse Allais

On y voit clairement que les éléments du texte sont réduits aux séquences de ca-ractères qui les composent. Par exemple, le titre n’est pas centré et il est écrit avec descaractères de la même taille que ceux du reste du texte.

Page 33: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Données 41

1.4.1.1.Les éléments d’un texte

Les éléments d’un texte s’organisent selon plusieurs niveaux.

Caractère. Un caractère est un signe appartenant à un système d’écriture. Ce signepeut être une lettre (A, Ç, É, a, à), un chiffre (0, 1, 2), un signe de ponctuation (. , -: ; ! ? ), un symbole (* = $ & C) ou un élément de parenthésage ([ « ). Pour ce qui estdes lettres, les différences dues à la casse (majuscule/minuscule, commeA eta) et auxaccents (commeà etâ) correspondent à des caractères distincts. Plus généralement, uncaractère est à la fois un objet logique (par exemple, une lettre minuscule) et un objetphysique (il peut appartenir à une police particulière ou avoir une taille déterminée).On compte également parmi les caractères l’espace, la tabulation et le retour à la ligne.Ces trois caractères se réalisent comme des déplacements etn’ont pas de forme gra-phique associée (on parle également de caractère non affichable). Dans un documentélectronique, les caractères sont représentés par des codes définis par une norme decodage (voir l’annexe A2 qui contient notamment la liste descaractères disponibles).

Mot. Un mot est une suite de caractères qui représente une forme dela langue. Lemot est l’une des unités logiques qui composent les paragraphes. Sur le plan typo-graphique, un mot est une séquence de lettres séparées par des espaces ou des signesde ponctuation. A côté des formes de la langue (Je, m’ ou étais), on considère habi-tuellement comme mots les séquences de chiffres (par exemple,1891), mais aussi leséléments de ponctuation et de parenthésage (les points-virgules, les virgules, les pointsde fin de phrase, les guillemets ou les parenthèses ; voir l’annexe A1 pour une présen-tation détaillée de la segmentation en mots). Le mot constitue, pour une exploitationinformatique d’un texte à visée linguistique, l’unité de référence : il est notammentd’usage de mesurer la taille d’un texte (ou d’un corpus) en nombre de mots.

Phrase. La phrase est une suite de mots autonome qui possède une unitéséman-tique : c’est un objet linguistique. Les phrases sont habituellement identifiées typogra-phiquement dans les textes par une majuscule au début de leurpremier mot et un pointà la fin.

Ligne (typographique). Une ligne de texte est une unité typographique du docu-ment : il s’agit d’une suite de caractères contigus horizontalement. Les lignes typogra-phiques d’un texte dépendent de la manière dont il est représenté physiquement sur lapage ou à l’écran. Elle varient notamment en fonction du typede justification, de lataille des caractères et de celle des marges. Ceci peut être illustré en reprenant le débutdu texte de la figure 1.4 et en l’écrivant avec des caractères plus gros et des margesplus larges :

Page 34: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

42 Perl pour les linguistes

Je m’étais pris d’une profonde sympathie pour cegrand flemmard de gabelou que me semblait l’imagemême de la douane, non pas de la douanetracassière des frontières terriennes, mais de labonne douane flâneuse et contemplative desfalaises et des grèves.

Figure 1.5. Extrait de la copie de l’ABU du recueil d’histoiresA se tordred’Alphonse Allais

Bien que le texte des figures 1.4 et 1.5 se trouve dans un seul etmême fichier, lenombre de lignes typographiques nécessaires à son affichageest plus important dansla seconde (passant de 4 à 6). Dans le même temps, la première ligne typographiqueJe m’étais pris... que mequi contient 16 mots dans la figure 1.4 n’en a plus que 10 (Jem’étais pris... pour ce) dans la figure 1.5. Cette notion de ligne étant totalement dé-pendante des caractéristiques d’affichage, elle n’est pas utilisée pour une exploitationdu contenu du texte : on lui préférera la notion de paragrapheou de ligne logique.

Paragraphe. Sur le plan typographique, un paragraphe est un bloc de textecom-posé de caractères. Ces blocs peuvent comporter plusieurs lignes typographiques,comme c’est le cas du texte de l’exemple précédent compris entre Je m’étais priset et des grèves.Sur le plan logique, un paragraphe est une suite de phrases (et doncde mots) explicitement séparée du reste du texte par un mouvement de retour à laligne. C’est ce mouvement qui est exprimé, lors de la saisie du texte, en frappant surla touche « Entrée ». Ce double statut du paragraphe fait que l’on préfère, pour lestextes électroniques, utiliser une dernière notion, cellede ligne logique.

Ligne logique. Une ligne logique (on parlera simplement de ligne dans la suite del’ouvrage) est une séquence de caractères terminée par un retour à la ligne (égalementappelé fin de ligne).

Une ligne logique peut ainsi correspondre à un paragraphe detexte (commel’exemple ci-dessus), mais aussi à un titre (A se tordre), ou tout autre élément, commeun item de liste, une réplique de dialogue, etc. On parle deligne videlorsque deuxfins de ligne se succèdent : le résultat affiché est un espacement vertical entre deuxsegments de texte, comme c’est le cas entre le titreUN PHILOSOPHEet le premierparagraphe qui le suit.

Cette notion de ligne est très importante, car elle constitue le segment de baseutilisé par les programmes informatiques qui analysent un fichier de texte.

1.4.1.2.Codage des fins de ligne

Une fin de la ligne peut être glosée comme « un passage au début de la lignesuivante » (on parle également de retour à la ligne).

Page 35: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Données 43

Formellement, ces séparateurs sont représentés dans les textes électroniques pardes caractères spécifiques (que l’on nomme également caractères spéciaux ou carac-tères non affichables).

Par exemple, les trois lignes de texte suivantes, lorsqu’elles apparaissent tellesquelles dans un texte brut :

undeuxtrois

sont représentées par la séquence de caractères :

u n ← d e u x ← t r o i s ←

où← représente le caractère de fin de ligne. Comme on le verra par la suite en mettanten place des programmes de manipulation de texte, ces caractères doivent être pris encompte spécifiquement.

Les systèmes d’exploitation des familles Windows et Unix utilisent deux sépara-teurs de ligne différents. Plus précisément, les systèmes Windows utilisent commeséparateur de ligne une séquence de deux caractères, notés CR (pourcarriage return,ou retour chariot) et LF (pourline feedou passage à la ligne). Ces deux caractèrescorrespondent en fait au double mouvement effectué par le curseur lors d’un change-ment de ligne : un mouvement vers la gauche pour le positionner en début de ligne,et un mouvement vertical pour descendre sur la ligne suivante. Les systèmes de typeUnix n’utilisent, eux, que le caractère LF pour ce double mouvement.

Malgré ces différences, on emploiera systématiquement le terme defin de lignepour exprimer ce séparateur, indépendamment du nombre et dela nature des caractèresutilisés pour le représenter. Les applications de manipulation de textes, et notammentles programmes Perl, s’adaptent automatiquement au codagedu système sur lequel ilssont exécutés.

Les utilisateurs d’un système Unix doivent toutefois porter attention aux difficultésqui peuvent se présenter lorsqu’ils manipulent des fichiersde texte provenant d’unsystème Windows. La section A1.1 (page 395) présente un utilitaire permettant deconvertir les fins de ligne.

1.4.1.3.Eléments de mise en page

Certains documents au format texte décrivent le découpage en lignes de l’éditionde l’œuvre à partir de laquelle le texte a été copié. Dans ce cas, les lignes logiquescorrespondent aux lignes typographiques d’origine, et nonpas aux paragraphes. C’est

Page 36: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

44 Perl pour les linguistes

par exemple le cas des documents qui proviennent de la base Frantext (voir para-graphe 1.5.1.3), diffusés par Gallica (voir paragraphe 1.5.1.1) et le CNRTL (voir pa-ragraphe 1.5.1.2). Dans certains cas, le texte comporte unereprésentation plus fidèleencore de la mise en page du document. Par exemple, les mots qui comportent descésures sont représentés comme tels1. Les découpages basés sur une mise en pageparticulière rendent plus difficile l’exploitation des textes car il faut reconstruire aupréalable leurs objets logiques mots et paragraphes.

1.4.1.4. Informations métatextuelles (entête)

Les documents qui contiennent des textes comportent généralement des informa-tions additionnelles comme lecopyright, le nom de l’auteur ou la table des matières.Ces informations sont dites métatextuelles car elles portent sur le texte mais n’en fontpas partie. Elles figurent habituellement dans une entête qui précède le texte propre-ment dit. C’est par exemple le cas du document présenté en figure 1.3. Son entêtecomporte une copie de la licence ABU suivie d’indications sur l’auteur de l’œuvre(Allais, Alphonse), son titre (A se tordre), son genre (prose), le copiste (Serge Thiriet),etc.

Afin de faciliter l’échange et le cumul des documents électroniques, la TEI2 (TextEncoding Initiative) a proposé un ensemble de recommandations pour l’encodage desinformations textuelles qui prévoit notamment une normalisation des entêtes (pourune présentation plus détaillée de la TEI, voir [HAB 05]). Denombreuses ressourcescomportent des entêtes TEI conformes à ce standard comme parexemple le lexiqueMorphalouprésenté au paragraphe 1.5.2.3. L’utilisation de ce standard n’est cepen-dant pas générale, notamment pour les ressources plus anciennes comme les archivesdu quotidienLe Mondeou le corpus de l’ABU qui disposent de leurs propres formatsd’entêtes.

Les informations contenues dans les entêtes se répartissent en deux groupes :

– des informations comme le titre du texte ou son résumé qui peuvent servir àl’observation de phénomènes linguistiques et que l’on peutconserver dans une versionen texte brut du document si elles n’y figurent pas déjà ;

– des informations indépendantes du texte comme la licence d’utilisation ou qui nesont pas de nature textuelle comme la table des matières, le genre du texte, le nombrede caractères ou l’adresse de l’éditeur. Celles-là doiventêtre exclues de l’exploitationdu texte à des fins linguistiques.

La forme et le contenu des entêtes sont très variables. En pratique, un traitementspécifique doit être défini pour chaque collection de documents (voir l’annexe A1 pour

1. Normalement, les césures sont gérées automatiquement parles logiciels de mise en page.2. http://www.tei-c.org/ .

Page 37: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Données 45

un exemple). Il faut cependant prendre soin de restaurer lesentêtes originales dans lesfichiers que l’on redistribue, et notamment leurs licences d’utilisation.

1.4.1.5.Manipulation d’un document au format texte

Un fichier contenant un document au format texte a, par convention, une extension.txt ; c’est-à-dire que le nom du fichier se termine par cette séquence de caractères(paragraphe 2.2.2, page 87). Il est toutefois possible de rencontrer des documents auformat texte contenus dans des fichiers ayant une autre extension (comme.abu pourles documents originaux du corpus de l’ABU).

Les documents au format texte se visualisent et se manipulent à l’aide d’un outilappelééditeur de texte, comme par exemple leBloc-notesdes systèmes Windows,mais également de nombreux autres outils facilement disponibles qui peuvent êtredotés de fonctionnalités plus complètes, comme l’éditeurSciTe (paragraphe 2.7.2,page 103).

1.4.2. Les autres formats de document et leur conversion en texte

Nous présentons quelques-uns des formats de document les plus courants : Doc,RTF, ODT, HTML, PDF, PostScript, TIFF et XML. Il en existe beaucoup d’autresque nous n’abordons pas ici comme ceux manipulés par des logiciels de bureautiquecomme les tableurs ou les outils de diaporama. De façon générale, la manipulation desdocuments conformes à un format donné se fait par l’intermédiaire de visionneuses quipermettent de les afficher, de les convertir en texte brut ou de les copier-coller dansd’autres applications. Rappelons que la conversion en texte brut consiste à créer unfichier qui ne contient que la séquence des caractères présents dans le document. Ellepeut toujours, en dernier ressort, être réalisée en copiant-collant le document à partird’un logiciel de visualisation adapté (Microsoft Word, Mozilla Firefox, Adobe Reader,etc.) dans un éditeur de texte comme leBloc-notesouScite (voir paragraphe 2.7.2).

Les manipulations présentées dans le reste de la section sont réalisées sous Win-dows au moyen de programmes courants qui disposent d’interfaces graphiques commeMicrosoft WordouAdobe Reader. Nous supposons donc que les utilisateurs disposentde ces outils sur leurs machines. Les manipulations destinées aux utilisateurs du sys-tème Unix sont, elles, réalisées au moyen de commandes en ligne. La lecture du cha-pitre 2 qui porte sur l’environnement de travail présente les notions de base et lesprocédures qui permettent de les exécuter.

1.4.2.1.Le format Doc deMicrosoft Word

Un format de document très répandu est celui qui est utilisé par le logiciel detraitement de texteMicrosoft Word, appelé couramment format Doc. Il est notam-ment utilisé par la Bibliothèque numériqueLes classiques des sciences socialesde

Page 38: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

46 Perl pour les linguistes

l’université du Québec à Chicoutimi (voir paragraphe 1.5.1.5) et pour des corpus plusspécialisés dont on trouve des exemples sur la FReeBank (voir paragraphe 1.5.1.6).

Extension. Les documents au format Doc peuvent être reconnus grâce à leur ex-tension.doc . C’est par exemple de cette façon que l’on peut identifier qu’un fichiernommécorpus_cafe.doccontient un document au format Doc3.

Visualisation. Plusieurs traitements de texte permettent de visualiser etd’éditerles documents Doc, notammentMicrosoft Word lui-même etOpenOffice Writer4. Lepremier est payant et uniquement disponible sous Windows etMacOS. Le second estgratuit et disponible sous Windows, Linux et MacOS. L’éditeur WordPadlivré avecles systèmes Windows permet également de lire les documentsDoc. Cet utilitaire n’estpas disponible pour les autres systèmes d’exploitation.

Conversion en texte.

Windows. La manière la plus simple pour convertir un document Doc en textebrut consiste à utiliser un traitement de texte compatible commeMicrosoft Word ouOpenOffice Writerou un éditeur commeWordPad. La procédure est identique avecces trois logiciels :

1) ouvrir le document ;

2) l’enregistrer au format texte en utilisant le menuFichier>Enregistrer sous...puis sélectionner :

- texte brut (*.txt)commeType de fichierpourMicrosoft Word;- texte (*.txt)commeTypepourOpenOffice Writer;- document textecommeTypepourWordPad;

et choisir le nom du fichier texte à créer.

Le document produit contient l’ensemble des paragraphes dutexte. La conversion deslistes, des notes de bas de page ou des tableaux varie en fonction du logiciel utilisé.Par exemple, les notes de bas de page ne sont pas conservées par WordPadmais ellesle sont parMicrosoft Wordqui les regroupe à la fin du fichier.

Unix. Le traitement de texteOpenOffice Writerpeut être utilisé sous Unix pourconvertir les documents Doc en texte brut. Le texte de ces documents peut aussi êtreextrait au moyen d’utilitaires gratuits commeAntiword5 oucatdoc6. Les commandespermettant de réaliser ces traitements sont :

3. Ce corpus peut être téléchargé à l’adresse Web suivante :http://freebank.loria.fr/ressource/corpus_cafe.doc .4. http://www.openoffice.org/ .5. http://www.winfield.demon.nl/ .6. http://freshmeat.net/projects/catdoc/ .

Page 39: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Données 47

antiword fichier.doc > fichier.txt

catdoc fichier.doc > fichier.txt

REMARQUE.– Il existe en réalité plusieurs formats Doc, qui correspondent aux diffé-rentes versions du logicielMicrosoft Word(97, 2000, 2002, 2003, XP, etc.). Si les dif-férences entre ces versions ne sont pas pertinentes pour uneexploitation linguistique,certains outils peuvent ne pas manipuler correctement les versions les plus récentes.Toutefois, la conversion en texte brut est généralement peusensible aux changementsde versions.

1.4.2.2.Le format RTF ouRich Text Format

Un autre format de document courant pour les traitements de texte est RTF ; déve-loppé lui aussi par la société Microsoft, il est souvent utilisé comme format d’enregis-trement pour les documents créés avecMicrosoft Word.

Extension. Les documents au format RTF ont une extension.rtf .

Visualisation. La plupart des outils qui permettent de visualiser et d’éditer les do-cuments Doc permettent également de le faire pour les documents RTF, en particulierMicrosoft Word, OpenOffice Writeret l’éditeurWordPad.

Conversion en texte.

Windows. La conversion des documents RTF en texte brut est identique àcelledes documents Doc. Elle peut être réalisée en utilisant les mêmes logiciels et lesmêmes procédures. Les fichiers texte produits sont également identiques.

Unix. Il existe sous Unix des utilitaires dédiés à la conversion entexte brut desdocuments RTF commeunrtf7. Comme l’indique son nom, ce logiciel supprime lesdirectives de mise en page qui figurent dans les documents pour ne conserver que letexte. La commande qu’il faut utiliser est :

unrtf --text fichier.rtf > fichier.txt

Cependant, la conversion au moyen de cet utilitaire n’est pas toujours satisfaisantedu fait des variations dans l’implémentation du format RTF.

7. http://www.gnu.org/software/unrtf/unrtf.html .unrtf est également disponible pour Windows à l’adresse :http://gnuwin32.sourceforge.net/packages/unrtf.htm .

Page 40: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

48 Perl pour les linguistes

1.4.2.3.Le format ODT ouOpenDocument Text

ODT est un format de document récent, utilisé notamment par la suite bureautiqueOpenOffice. Il fait l’objet d’une norme internationale et pourrait s’imposer à l’avenircomme un standard pour les documents officiels8.

Extension. L’extension des documents ODT est.odt .

Visualisation. Les documents ODT peuvent être visualisés et édités par le traite-ment de texteOpenOffice Writer. Sous Linux, il est également possible de les mani-puler en utilisant le traitement de texte de la suiteKOffice9.

Conversion en texte.

Windows. La conversion des documents ODT en texte brut est identique àcelledes documents Doc et RTF. Elle peut être réalisée en utilisant OpenOffice Writerselonla même procédure.

Unix. On peut aussi utiliser sous Unix un utilitaire dédié à la conversion desdocuments ODT en texte brut commeodt2txt10. La commande à utiliser est :

odt2txt fichier.odt > fichier.txt

1.4.2.4.Le format HTML ouHyper Text Markup Language

HTML est le format des pages Web. Il s’agit d’un format de document : HTML nedispose pas d’une véritable notion de page (voir ci-dessous). HTML fait l’objet d’unstandard établi par le consortium W3C11 (World Wide Web Consortium).

Le chapitre 10 de cet ouvrage est entièrement consacré à l’exploitation des pagesWeb, et aborde notamment leur téléchargement et leur transformation en texte brut.

Extension. Les fichiers qui contiennent des documents HTML peuvent avoir lesextensions.htm ou .html .

Visualisation. Les documents HTML peuvent être visualisés par les navigateursWeb commeMozilla Firefox12 ou Internet Explorer. Signalons que les navigateurs

8. Le format ODT utilise la norme XML pour stocker les informations de mise en page.9. http://www.koffice.org/ .10. http://stosberg.net/odt2txt/ .odt2txt est également disponible pour Windows à la même adresse.11. http://www.w3.org/ .12. http://www.mozilla.com/firefox/ .

Page 41: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Données 49

Web disposent par ailleurs de fonctionnalité qui permettent l’affichage de contenusqui ne sont pas décrits en HTML.

Conversion en texte.

Windows. Les navigateurs Web offrent la possibilité de sauvegarder les docu-ments HTML au format texte :

1) ouvrir le document dans un navigateur ;

2) l’enregistrer au format texte en utilisant le menuFichier>Enregistrer sous...puis sélectionner :

- fichiers textecommeTypepourFirefox ;- fichier texte (*.txt)commeTypeet Europe occidentale (ISO)commeCodage

pourInternet Explorer;et choisir le nom du fichier texte à créer.

Cette opération ne permet pas toujours d’obtenir le résultat souhaité. Les raisons del’échec de la sauvegarde au format texte sont diverses. Par exemple, certaines partiesdu texte affiché dans les pages Web sont des images (comme les boutons ou les cartescliquables) qui ne sont pas conservées dans la copie en textebrut. Rappelons que pourune page particulière, la conversion peut être réalisée parun simple copier-coller.

Unix. La conversion en texte des documents HTML peut aussi être réaliséecomme sous Windows au moyen d’un navigateur.

Pour les deux types de système, le chapitre 10 présente une série de programmesPerl permettant de réaliser cette conversion.

1.4.2.5.Le format PDF ouPortable Document Format

PDF est un format de document conçu par la société Adobe. Il s’est imposé au-jourd’hui comme un format standard pour les documents électroniques diffusés surle Web car il garantit un affichage et une impression identique sur toutes les plate-formes. Le format PDF est aussi souvent utilisé pour diffuser des documents qui ontété numérisés. C’est par exemple le cas pour une grande partie des œuvres de la bi-bliothèque numérique Gallica (voir paragraphe 1.5.1.1). Ces documents sont en réalitédes photographies numériques des documents papier originaux, et n’ont pas à propre-ment parler de contenu textuel exploitable : les caractèresn’y sont pas représentéssous forme logique.

Extension. Les documents PDF peuvent être reconnus par leur extension.pdf .

Page 42: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

50 Perl pour les linguistes

Visualisation. Plusieurs outils de visualisation des documents PDF sont dispo-nibles gratuitement à la fois sous Windows (notammentAdobe Reader13etGSview14)comme sous Unix (Adobe Reader, xpdf15 ougv16).

Conversion en texte. La conversion en texte brut des documents PDF préserve lescaractéristiques principales de leur mise en page, notamment le découpage en lignes etla césure des mots qui se trouvent en fin de ligne. De même, les entêtes, les numéros depage et les notes de bas de page sont insérés dans la position qu’ils occupent dans lespages affichées. La révision manuelle du texte brut obtenu est donc souvent nécessaire.

Windows. Les visionneusesAdobe Readeret GSview permettent de convertirfacilement un document PDF en texte :

1) ouvrir le document à convertir ;

2) le sauvegarder au format texte par l’intermédiaire du menu :- Fichier>Enregistrer au format texte...pourAcrobat Reader;- Edit>Text extract...pourGSview;

et choisir le nom du fichier texte à créer.

Cette procédure ne permet pas de convertir les documents quiont été produits parnumérisation. Ces derniers doivent être traités par un outil de reconnaissance optiquede caractères (OCR) commeOmnipage17 ou OmniFormat18 (voir ci-dessous). Lestextes produits par ces OCR sont de qualité très variable. Ils peuvent contenir un grandnombre d’erreurs et être dans certains cas totalement inutilisables.

Unix. Adobe Readerpermet de convertir les documents PDF de la même façonque sous Windows. La création d’une copie au format texte peut aussi être réaliséeau moyen d’un outil dédié commepdftotext qui est fourni avec l’utilitairexpdf. Lasyntaxe de la commande permettant de réaliser cette opération est :

pdftotext fichier.pdf fichier.txt

1.4.2.6.Le format PostScript

PostScript est un langage informatique dédié à la description des documents, déve-loppé par la société Adobe. Comme PDF, le format PostScript permet une description

13. http://www.adobe.com/fr/ .14. http://www.cs.wisc.edu/~ghost/gsview/ .15. http://www.foolabs.com/xpdf/ .16. http://www.gnu.org/software/gv/ .17. http://www.nuance.com/omnipage/ .18. http://www.omniformat.com/ .

Page 43: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Données 51

des pages qui est indépendante des plate-formes et des systèmes d’exploitation. Ceformat est essentiellement utilisé dans les environnements Unix.

Extension. Les documents PostScript portent l’extension.ps .

Visualisation. Les documents PostScript peuvent être visualisés en utilisantGSView sous Windows etgv sous Unix.

Conversion en texte. La conversion des documents PostScript est similaire à celledes documents PDF et produit des fichiers texte qui tiennent compte de la mise enpage.

Windows. La conversion du PostScript en texte peut être réalisée sousWindowsau moyen de la visionneuseGSViewde façon identique à la conversion des documentsPDF.

Unix. L’utilitaire pstotext permet de convertir en texte les documents Post-Script. La syntaxe de la commande est :

pstotext fichier.ps > fichier.txt

1.4.2.7.Le format TIFF ouTagged Image File Format

TIFF est un format dédié au stockage des images et notamment des photographies.Il est utilisé pour les documents produits par numérisation(c’est-à-dire par les scan-ners).

Extension. Les documents TIFF peuvent avoir les extensions.tif et .tiff .

Visualisation. Les images au format TIFF sont affichées directement sous Win-dows par l’Explorateur Windowssous forme de vignettes (voir paragraphe 2.2.1, page87). On peut également les visualiser au moyen d’outils de manipulation d’imagescommeMicrosoft Office Document Imagingou l’applicationAperçu des images etdes télécopies Windows. Il existe sous Unix aussi plusieurs outils permettant d’affi-cher et de manipuler les images au format TIFF, notammentImageMagick19.

Conversion en texte. La conversion des textes scannés est réalisée au moyend’OCR commeOmnipageet OmniFormatsous Windows. Sous Unix, l’extractiond’un texte à partir d’un document au format TIFF peut être réalisée au moyen d’unlogiciel commeGocr20 ou en utilisant un outil de numérisation commeXsane21.

19. http://www.imagemagick.org/ .20. http://jocr.sourceforge.net/ .21. http://www.xsane.org/ .

Page 44: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

52 Perl pour les linguistes

1.4.2.8.Le format XML ouExtended Markup Language

XML est un format générique de documents qui répond à des besoins plus com-plexes de représentation et d’exploitation de leur structure interne. Ce format est no-tamment très souvent adopté pour des documents annotés (contenant du texte et desinformations supplémentaires sur celui-ci, notamment desannotations linguistiques).

Le cas de XML est très différent des autres formats présentésici : il n’existe pasd’outil générique de visualisation du document, et tout traitement (comme la conver-sion en texte) doit être adapté au type de document.

Le chapitre 9 est entièrement consacré à ce format : le lecteur y trouvera une pré-sentation générale de ses principes ainsi qu’un ensemble deprogrammes permettantson exploitation.

1.4.2.9.Le convertisseurOmniFormat

OmniFormatest en réalité un outil général de conversion de format. Ce logicielpermet de traduire en une seule fois un ensemble de documentsde formats diverscomme PDF, Doc, HTML, RTF ou TIFF vers un format cible donné, notamment letexte brut. La procédure permettant d’extraire les textes d’un ou de plusieurs docu-ments est la suivante :

1) créer un nouveau répertoire dans lequel seront placées les copies au format textebrut ;

2) recopier dans ce répertoire les fichiers à convertir. Cette copie est nécessaireparce qu’OmniFormatdétruit les fichiers de départ et les remplace par le résultatdela conversion ;

3) lancerOmniFormat;

4) sélectionner le répertoire contenant les fichiers à convertir et spécifier que leformat cible est TXT.

OmniFormatremplace alors chaque document présent dans le répertoire par saversion texte. Les documents produits par numérisation sont convertis par OCR.

1.4.3. Les archives compressées

Les ressources qui sont destinées au traitement informatique sont souvent distri-buées sous forme d’archives compressées. C’est le cas notamment du lexiqueMor-phalou(voir paragraphe 1.5.2.3), des corpus du CNRTL (voir paragraphe 1.5.1.2) ouduCorpus de bitextes anglais-français(BAF22) du laboratoire RALI de l’université de

22. http://rali.iro.umontreal.ca/Ressources/BAF/ .

Page 45: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Données 53

Montréal. Les archives compressées sont le résultat de deuxopérations : l’archivageet la compression.

Archivage. L’archivage consiste à rassembler dans un fichier unique un ensemblede documents et de répertoires (voir section 2.2, page 86) qu’il est alors possible demanipuler (sauvegarder, envoyer, recevoir, dupliquer) defaçon groupée. Les archivessont créées par des outils spécialisés. Les mêmes outils servent généralement aussià en extraire le contenu, c’est-à-dire à créer une copie des fichiers et des répertoiresarchivées. L’extraction des fichiers est un préalable à leurutilisation : la plupart desprogrammes ne sont pas en effet capables de manipuler directement les fichiers conte-nus dans une archive.

Les archives les plus simples sont non compressées. Elles sont au format TAR(Tape ARchiver; extension.tar ) et sont surtout utilisées sous Unix. De nombreuxoutils d’archivage permettent d’en extraire le contenu commeWinZip23, WinRAR24,PowerArchiver25 et 7-zip26 sous Windows. Sous Unix, on peut utiliser la commandetar ou un logiciel disposant d’une interface graphique commeXarchiver27.

Unix. La commande qui permet d’extraire le contenu d’une archive TAR aumoyen de l’utilitairetar est :

tar -xf fichier.tar

Compression. La compression des fichiers est un procédé qui permet de décrireleur contenu dans un codage qui minimise leur taille. Elle est très utile pour les don-nées volumineuses comme les archives contenant de gros corpus et les lexiques degrande taille car elle permet de réduire l’espace qu’elles occupent sur le disque et d’ac-célérer leurs transferts et leurs téléchargements. La compression est particulièrementefficace pour les documents textuels dont la réduction de la taille atteint couramment60 % à 95 %.

Il existe plusieurs formats de données compressées comme ZIP (extension.zip ),GZIP (extension.gz) , RAR (extension.rar ), BZIP2 (extensions.bz2 ou .bz ) ou7z (extension.7z ). Parmi ces derniers, GZIP et BZIP2 sont des formats de compres-sion de fichiers isolés tandis que ZIP, RAR et 7z sont des formats d’archives compres-sées.

23. http://www.winzip.com/ .24. http://www.rarlab.com/ .25. http://www.powerarchiver.com/ .26. Il s’agit d’un utilitaire gratuit qui peut être téléchargéà l’adresse suivante :http://www.7-zip.org/ .7-zip est également disponible sous Unix.27. http://xarchiver.xfce.org/ .

Page 46: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

54 Perl pour les linguistes

Windows. Sous Windows, la décompression des archives ZIP est directementintégrée à l’Explorateur Windows. Ce dernier permet de les ouvrir de manière trans-parente comme des répertoires classiques (la seule différence avec un répertoire nor-mal est que les archives ZIP ont le typeDossier compressé). Ces archives peuvent êtredécompressées en utilisant l’itemExtraire tous...du menu contextuel que l’on obtientpar un clic droit de la souris dans la fenêtre dans laquelle l’archive est affichée. Onpeut aussi utiliser les utilitaires polyvalentsWinZip, WinRAR, PowerArchiverou 7-zip qui permettent de décompresser les archives ZIP et les autres formats de fichiersd’archives compressées.

Unix. Les formats de compression courants sous Unix sont GZIP et BZIP2.On peut décompresser les fichiers de ces deux formats en utilisant respectivement lesprogrammesgunzipet bunzip2. Les lignes de commande correspondantes sont :

gunzip fichier.gz

bunzip2 fichier.bz2

Chacune de ces commandes substitue au fichier compressé le résultat de sa décom-pression. Le nom du fichier résultat est obtenu à partir de celui du fichier compresséen lui enlevant l’extension.gz (resp..bz2 ).

Les archives TAR peuvent être compressées dans ces deux formats. Celles qui sontdans le format GZIP portent l’extension.tgz ou .tar.gz ; celles qui sont au formatBZIP2 ont une extension.tbz2 , .tbz , .tar.bz2 ou .tar.bz . Leur décompressionet l’extraction de leur contenu peuvent être réalisées en utilisant la commandetar dela manière suivante :

tar -xzf fichier.tgz

tar -xjf fichier.tbz2

Les archives ne sont pas supprimées après la décompression.

Pour les archives ZIP, 7z, RAR, on utilise les programmes dédiés unzip, 7z etunrar. Les commandes permettant d’extraire le contenu des archives ayant ces formatssont respectivement :

unzip fichier.zip

7z x fichier.7z

unrar e fichier.rar

Là encore, les archives ne sont pas supprimées après la décompression.

Page 47: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Données 55

1.5. Panorama des ressources disponibles

Les formats qui viennent d’être présentés couvrent la plus grande partie desressources textuelles et lexicales disponibles. La présente section est consacrée àleur identification et à leur localisation. Elle propose un petit inventaire qui signalequelques-unes des ressources incontournables et donne uneidée de la diversité desdonnées que l’on peut utiliser pour des recherches en linguistique.

Certaines de ces ressources sont gratuites, d’autres payantes. Mais dans tous lescas, leur utilisation ne peut se faire que dans le cadre de la licence accordée par lesdétenteurs ducopyright. Il est indispensable de prendre connaissance de ces informa-tions avant toute utilisation.

On distingue généralement les droits des textes de ceux des copies qui en sontfaites par une personne ou une association. Ainsi, un texte peut être dans le domainepublic mais pas le fichier qui en contient une copie. Globalement, toutes les ressourcesdu domaine public présentées dans cette section peuvent être utilisées librement pourdes travaux de recherche. Leur redistribution, par exemplesur un site Web, peut fairel’objet de restrictions de la part des détenteurs des droitssur les fichiers. Pour uneutilisation à des fins commerciales, un accord spécifique avec les détenteurs des droitssur la ressource doit être établi.

Pour les ressources sous droits, comme les archives du quotidienLe Monde, au-cune utilisation ne peut se faire sans l’autorisation du détenteur des droits ou d’un deses représentants, par exemple, un distributeur.

1.5.1. Les ressources textuelles

Les ressources textuelles sur lesquelles peuvent s’appuyer des recherches en lin-guistique sont nombreuses et présentent une grande diversité de genres (littérature,journaux, textes officiels, scientifiques, etc.), de formats, de modes de diffusion et deconditions d’utilisation. Nous n’en présentons ici que quelques-unes. Un travail depréparation est souvent nécessaire pour intégrer les textes d’une ressource dans uncorpus de travail. Cette préparation est en général spécifique à la ressource du fait dela variabilité des formats et des contenus. L’effort doit donc être répété pour chaquenouvelle ressource. En contrepartie, une fois le corpus d’étude constitué, les textes quile composent sont disponibles sans surcoût pour toutes les recherches ultérieures.

1.5.1.1.Gallica

La Bibliothèque nationale de France (BnF) propose une base importante de texteslittéraires intégraux en français.

Page 48: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

56 Perl pour les linguistes

Nom. Gallica

Adresse. http://gallica.bnf.fr/

Contenu. Le fonds de cette bibliothèque numérique se compose de 90 000ou-vrages numérisés (c’est-à-dire scannés). Gallica contient aussi 1 250 œuvres essen-tiellement littéraires, au format texte, du domaine public, issues de la base Frantext(voir paragraphe 1.5.1.2), desClassiques Garnier(Bibliopolis28) et des Editions Aca-média et Champion. Les œuvres appartiennent essentiellement auXIX e siècle ou sontplus anciennes.

Formats. Les images des pages des ouvrages numérisés sont au format PDF. Letexte de ces ouvrages n’est malheureusement pas directement exploitable par des trai-tements informatiques (voir paragraphe 1.4.2.5). A l’inverse, les œuvres au formattexte sont très bien adaptées à ces traitements.

Utilisation. Pour constituer un corpus d’étude à partir de ces documents,il faut lesvisualiser au moyen d’un navigateur Web et les enregistrer un par un sur son ordina-teur (sélectionner le mode d’affichageTexte seuldans l’interface du site Web). C’est untravail répétitif et fastidieux, mais néanmoins rentable car il permet de disposer d’uncorpus facilement réutilisable. Les textes obtenus comportent une entête qui indiqueleur origine (il faut la supprimer avant de les utiliser, voir section A1.3). Ceux qui pro-viennent desClassiques Garnieret des Editions Acamédia sont simplement découpésen paragraphes. En revanche, les textes issus de Frantext présentent un découpage enlignes et en pages identique à celui des versions imprimées àpartir desquelles ils ontété copiés. Les numéros de page figurent notamment au milieu des textes et doiventfaire l’objet d’un « nettoyage » spécifique.

Licence. L’utilisation des documents mis en ligne sur Gallica est libre dedroits dans le cadre d’une utilisation privée et/ou d’une diffusion gratuite(avec mention de la source des données : « Bibliothèque nationale de France ;http://gallica.bnf.fr/ »).

1.5.1.2.Frantext par le CNRTL

Le Centre national de ressources textuelles et lexicales (CNRTL), adossé au la-boratoire ATILF29, propose un ensemble de ressources utiles pour les recherches enlinguistique dont un corpus extrait de la base Frantext (voir paragraphe 1.5.1.3).

28. http://www.bibliopolis.net/ .29. Analyse et traitement informatisé de la langue française, CNRS et université de Nancy :http://www.atilf.fr .

Page 49: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Données 57

Nom. Corpus Frantext

Adresse. http://www.cnrtl.fr/corpus/frantext/

Contenu. 500 textes du domaine public, provenant de la base Frantext.

Format. Les textes de cette collection sont au format XML (voir chapitre 9) etconformes aux recommandations de la TEI (voir paragraphe 1.4.1.4).

Utilisation. Le site Web permet de constituer facilement un corpus en sélectionnantles textes que l’on souhaite y inclure puis en le téléchargeant en une seule fois sousforme d’une archive ZIP (voir paragraphe 1.4.3). Cependant, l’exploitation de cetteressource est réservée aux utilisateurs qui disposent de connaissances minimales dansla manipulation du format XML et des systèmes de codage, du type de celles qui sontprésentées dans le chapitre 9 et dans l’annexe A2.

1.5.1.3.Frantext par Frantext

Frantext, la première base textuelle du français, est un corpus bien connu des lin-guistes, développé et géré par l’ATILF.

Nom. Frantext

Adresse. http://www.frantext.fr/

Contenu. Frantext contient plus de 3 000 œuvres totalisant plus de 220millions demots.

Utilisation. Cette base est uniquement accessible sur abonnement30 (la plupart desuniversités et bibliothèques disposent d’un tel accès). Son interrogation se fait parl’intermédiaire d’une interface Web qui propose des fonctionnalités permettant l’ex-traction et l’affichage de segments de texte. Les textes qui la composent ne peuventdonc pas être exploités par des programmes externes.

L’interface utilisateur de la base Frantext permet cependant de rapatrier les résul-tats des requêtes, c’est-à-dire les contextes d’occurrence des éléments étudiés. Lesréponses sont limitées à 50 000 extraits par requête ; la taille maximale d’un extraitest de 300 mots pour un texte sous droit et de 3 pages pour un texte libre de droit.On peut fractionner la requête ou le corpus de travail dans lecas où le nombre desrésultats dépasse 50 000. Les réponses rapatriées peuvent être compilées en un corpusd’attestations qui peut être exploité au moyen de programmes Perl. Dans ce cas, lesprogrammes doivent être adaptés pour prendre en compte le découpage du corpus enextraits et la présence d’une petite entête au début de chaque résultat.

30. http://www.atilf.fr/atilf/produits/frantext.htm .

Page 50: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

58 Perl pour les linguistes

1.5.1.4.ABU

L’Association des bibliophiles universels (ABU) est une association de loi 1901qui propose une collection d’œuvres complètes. Ses donnéessont hébergées sur le siteWeb du Conservatoire national des arts et métiers (CNAM).

Nom. Bibliothèque universelle

Adresse. http://abu.cnam.fr/

Contenu. Cette base comporte 288 textes littéraires (101 auteurs différents ; envi-ron 11 millions de mots) qui ne sont plus sous droits, et sont donc pour la plupart an-térieurs auXX e siècle. Elle n’est malheureusement plus alimentée en nouveaux textesdepuis janvier 2002.

Format. Toutes les œuvres sont disponibles au format texte.

Utilisation. L’interface d’interrogation sur le site Web propose l’affichage dutextecompletde chacune des œuvres, sans formatage (non formaté). On peut ainsi les sau-vegarder très simplement par l’intermédiaire d’un navigateur Web. Les fichiers distri-bués par l’ABU comportent une entête qui contient une copie de la licence d’utilisa-tion ainsi que des informations plus spécifiques comme le nomde l’auteur ou celui ducopiste (voir section 1.1). Les textes des œuvres sont découpés en paragraphes.

Licence. La licence ABU accorde le droit d’utiliser librement ces textes pour l’en-seignement et la recherche.

1.5.1.5.Les classiques des sciences sociales

Des corpus d’œuvres non littéraires sont également disponibles sur le Web. Il existenotamment une importante base de textes en sciences sociales mise en ligne par l’uni-versité du Québec à Chicoutimi31. Ce projet de bibliothèque numérique est très actif.

Nom. Les classiques des sciences sociales

Adresse. http://classiques.uqac.ca/

Contenu. La base comprend plus de 2 000 œuvres originales de plus de 700auteursdifférents ; de nouveaux textes y sont ajoutés régulièrement. Ils présentent une grandediversité de domaines (histoire, économie, philosophie, anthropologie, sociologie, lin-guistique, etc.), et sont de taille et de nature variées (articles, essais, monographies,dictionnaires, traductions scientifiques).

31. http://www.uqac.ca/ .

Page 51: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Données 59

Formats. Ces textes sont proposés dans plusieurs formats : Doc, PDF etRTF.

Utilisation. Les documents proposés peuvent être téléchargés au moyen d’un na-vigateur Web puis visualisés en utilisant la visionneuse oul’éditeur par défaut pourle format sélectionné. Le site Web de cette bibliothèque numérique étant organisé defaçon arborescente, le téléchargement de ces documents peut aussi être réalisé en uti-lisant un logiciel commeHTTrack32 ouwget33 (voir paragraphe 1.6.2).

Licence. Les textes proposés sont tous du domaine public. En revanche, les fichiersréalisés par l’équipe des Classiques sont soumis à une licence qui indique qu’ils « sontdisponibles pour une utilisation intellectuelle et personnelle, mais non commerciale »,et qu’ils ne peuvent pas être redistribués, « même avec la mention de leur prove-nance ».

1.5.1.6.FReeBank

La FReeBank est une base de corpus en français essentiellement composée detranscriptions de dialogues. Il s’agit également d’une desrares collections de textesannotés, c’est-à-dire disposant d’informations linguistiques explicitées (portant sur lamorphologie, la syntaxe ou la coréférence).

Nom. FReeBank

Adresse. http://freebank.loria.fr/

Contenu. La FReeBank contient 274 dialogues, trilogues, quadrilogues et mono-logues répartis en 9 corpus (AIR FRANCE, CIO, GOCAD, Microfusées, Ozkan, Re-nault, SNCF, PIC, café). Signalons également la présence d’un corpus journalistiquecatégorisé de 100 000 mots, provenant du quotidienLe Monde(1987), et d’extraitsannotés duPère Goriot(Honoré de Balzac) et deAlice au pays des merveilles(LewisCaroll).

Formats. Ces textes sont proposés aux formats texte, Doc et XML. Pour ce dernier,les annotations sont conformes aux recommandations de la TEI :

32. http://www.httrack.com/ .33. http://www.gnu.org/software/wget/ .

Page 52: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

60 Perl pour les linguistes

Corpus FormatsAIR FRANCE texte ; XML-TEICIO texte ; XML-TEIGOCAD texte ; XML-TEIMicrofusées XML-TEIOzkan XML-TEIRenault texte ; XML-TEISNCF texte ; XML-TEIPIC Doc ; XML-TEIcafé Doc

Licence. Les corpus de la FReeBank ne comportent pas de licence d’utilisationstandard. Cependant, les entêtes TEI de la plupart d’entre eux précisent que ces docu-ments peuvent être librement utilisés à des fins de rechercheacadémique.

1.5.1.7.Littérature grise

Un grand nombre de productions ne sont pas publiéesvia les circuits commerciauxd’édition et de diffusion. C’est notamment le cas des thèses, des actes de colloque, desrapports de recherche, des supports de cours, etc. Ce type d’œuvres, généralementappelé « littérature grise », est diffusé de plus en plus largement sur des sites Webspécialisés. Citons par exemple les services mis en place par le Centre pour la com-munication scientifique directe (CCSD) du CNRS.

Nom. Hyper Article en Ligne (HAL)

Adresse. http://www.ccsd.cnrs.fr/

Contenu. Le serveur HAL comporte plus de 45 000 articles scientifiquesau formatPDF, et le serveur TEL (Thèses en ligne) plus de 7 000 thèses34. Ces articles scienti-fiques et thèses relèvent de l’ensemble des disciplines scientifiques : mathématiques,physique, chimie, sciences de la vie, sciences humaines, etc. Ils peuvent être très utilespour mener par exemple des études sur des langues de spécialité.

Licence. La totalité de ces documents est sous droits d’auteurs. Il faut obtenir l’au-torisation de ces derniers avant toute utilisation.

34. Les thèses les plus anciennes sont des documents numérisés. Elles ne sont pas directementutilisables pour des traitements automatiques. Certains documents sont en anglais.

Page 53: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Données 61

D’autres dépôts de thèses existent en France comme ceux des grandes écoles35

(mais certaines thèses sont rédigées en anglais) ainsi que dans d’autres pays franco-phones comme la Suisse36 ou le Canada37.

La littérature grise inclut également les revues scientifiques, essentiellement dif-fusées par abonnement. Un grand nombre d’entre elles accordent un accès gratuit àleurs archives sur leurs sites Web. L’accès aux revues scientifiques peut se faire parl’intermédiaire de portails comme le site français d’édition électronique scientifiqueRevues.org38. Un portail équivalent existe au Canada : Erudit39.

1.5.1.8.Documentation administrative

Les recherches en linguistique peuvent aussi s’appuyer surbien d’autres genresde documents, notamment sur les archives de textes administratifs comme leJournalOfficiel40, les Bulletins Officiels des ministères41 ou le Journal Officiel de l’UnionEuropéenne42. Tous ces textes sont du domaine public et peuvent être utilisés sansrestriction. Leur téléchargement peut être réalisé au moyen d’un navigateur Web. Enrevanche, il n’est pas facilement automatisable, ces documents étant souvent générésà la demande par les sites Web qui les publient.

Ces textes sont fortement structurés : chaque décret, arrêté ou circulaire comporteun titre, une liste de lois, codes et décrets sur lesquels repose les décisions, une listed’autorités signataires, etc. Cette structure doit être analysée finement pour identifieret extraire les éléments textuels. Au final, la taille du texte obtenu n’est souvent pastrès importante au regard des efforts qu’il faut réaliser pour l’extraire.

1.5.1.9.Web

Les documents considérés jusqu’ici sont des versions électroniques de textes pu-bliés. Mais de plus en plus de documents ne sont diffusés que sur le Web, généralementsur des sites spécialisés (annonces classées, recettes de cuisine, information médicale,associations professionnelles). Le téléchargement de cestextes peut se faire manuel-lement en utilisant un navigateur ou au moyen de programmes (voir chapitre 10).Cependant, la fluctuation importante des formats et des formes de présentation des

35. http://pastel.paristech.org/ .36. http://doc.rero.ch/ .37. http://www.collectionscanada.ca/thesescanada/index- f.html .38. http://www.revues.org/ .39. http://www.erudit.org/ .40. http://www.journal-officiel.gouv.fr/ .41. http://www.legifrance.gouv.fr/html/bo/bo.htm .42. http://eur-lex.europa.eu/JOIndex.do .

Page 54: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

62 Perl pour les linguistes

informations ne permet pas d’envisager la réalisation d’outils généraux de télécharge-ment et de normalisation. Il est souvent nécessaire de développer des programmes trèsspécifiques pour les pages Web de chaque site.

Le Web propose également des données utiles pour étudier le dialogue et les inter-actions liés au développement des nouvelles technologies de communication, notam-ment les archives de listes de diffusion, les blogs ou les chats (forums de discussion entemps réel). Ces archives sont relativement bien indexées par les moteurs de rechercheet elles sont de ce fait faciles à localiser.

Enfin, certaines études linguistiques utilisent désormaisdirectement le Webcomme corpus, en exploitant directement les moteurs de recherche. Le chapitre 10détaille les techniques permettant une telle approche.

1.5.1.10.Archives de journaux payantes

A côté des bibliothèques numériques qui donnent accès gratuitement à des œuvresque l’on peut réunir en corpus, il existe des ressources payantes, notamment les ar-chives de journaux. Elles sont souvent utilisées pour les recherches en linguistiquescar :

– elles donnent accès à un français plus récent que les textesdu domaine publicdes bibliothèques numériques ;

– elles sont de très grande taille (la taille de la base Frantext (voir para-graphe 1.5.1.3) est par exemple la moitié de celle des archives du quotidienLe Mondeactuellement disponibles) et sont donc adaptées à l’observation de phénomènes rares ;

– la langue journalistique est parfois considérée comme représentative du françaisstandard actuel.

L’un des principaux distributeurs est l’association ELRA43 (Association euro-péenne pour les ressources linguistiques) dont le catalogue contient des archives duMondeet duMonde Diplomatiqueet de l’année 1998 du mensuelLa Recherche. Lalicence d’utilisation accordée par ELRA permet l’utilisation de ces ressources pour larecherche.

1.5.1.11.Ressources textuelles redistribuées dans l’environnement de travail

L’environnement de travail mis à disposition sur le site d’accompagnement du livrecontient les corpus textuels suivants :

1) les textes de l’ABU dans leur version originale et dans plusieurs versions,les rendant directement utilisables par les programmes présentés dans la suite de

43. http://catalog.elra.info/ .

Page 55: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Données 63

l’ouvrage (notamment segmentés et catégorisés au moyen duTreeTaggervoir pa-ragraphe 1.7.3). Ces différentes versions sont identifiables par les extensions des fi-chiers qui les contiennent :.abu pour la version originale ;.txt pour le texte débar-rassé de l’entête et du séparateur final ;.seg pour le texte segmenté en mots (voirparagraphe 1.7.1) ;.tag pour la version catégorisée par leTreeTagger(voir para-graphe 1.7.3). Par exemple, pour le textetordre1 présenté en section 1.1, l’archivecontient les fichierstordre1.abu , tordre1.txt , tordre1.seg et tordre1.tag ;

2) le corpus Ozkan de la FReeBank dans sa version originale. Nous remercionsSusanne Alt, Jean Caelen et Nadine Ozkan pour nous avoir autorisés à exploiter etdistribuer ce corpus.

1.5.2. Les ressources lexicales

Si les textes constituent un support privilégié pour l’observation de la langue,d’autres ressources, notamment lexicographiques, sont aussi très utiles pour la re-cherche en linguistique. Elles permettent par exemple de créer rapidement des listesde mots en s’appuyant sur des critères de forme et de catégorie (voir figure 1.1). Ceslistes peuvent aussi être utilisées pour rechercher des occurrences et des constructionsdans les textes d’un corpus.

Pour une recherche particulière, le choix d’un lexique dépend de la disponibilitédes informations dont on a besoin, de la qualité de la ressource et de la simplicité deson utilisation (sont-elles faciles à analyser ? peut-on extraire aisément les informa-tions utiles ?) La qualité d’un lexique dépend avant tout de la révision humaine de soncontenu mais aussi de la cohérence de son codage et de sa complétude (c’est-à-dire desa couverture).

Les ressources lexicales du français sont nombreuses et faciles à localiser. Cellesqui sont présentées ci-dessous sont toutes gratuites et, à l’exception deMorphalou(voir paragraphe 1.5.2.3), sont incluses dans l’environnement de travail mis à dispo-sition sur le site d’accompagnement du livre. L’intégration deMorphaloudans l’en-vironnement de travail doit être effectué individuellement par chaque utilisateur (voirparagraphe 1.5.2.7).

1.5.2.1.Les listes de formes

Les ressources lexicales plus simples sont les listes de formes commedico.

Nom. dico

Adresse. Le lexique original est disponible à l’adresse :

ftp://ftp.ox.ac.uk/pub/wordlists/french/dico.Z

Page 56: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

64 Perl pour les linguistes

Le codage des diacritiques n’y étant pas standard, le site d’accompagnement contientune version normalisée distribuée avec les systèmes Linux.

Echantillon. dicocontient pour le motlessivel’entrée :

lessive

Figure 1.6. Le motlessivedansdico

Contenu. 140 000 formes fléchies du français

Format. Le lexique est au format texte. Les mots y sont listés un par ligne, parordre lexicographique.

Sur le plan linguistique, une liste de formes présente un intérêt limité : elle permetseulement de vérifier si une forme particulière appartient ou non à la liste.

Licence. Ce lexique est distribué sous licence GNU GPL (GNU General PublicLicenseou Licence Publique Générale GNU)44. Cette licence standard (utilisée no-tamment pour la diffusion de logiciels libres) autorise l’exploitation, la modificationet la redistribution de la ressource (sous certaines conditions).

1.5.2.2.La liste de mots communs de l’ABU

On trouve heureusement sur le Web des lexiques plus riches comme laliste de motscommunsde l’ABU (Association des bibliophiles universels, voir paragraphe 1.5.1.4)qui fournit une description morphosyntaxique complète pour chaque forme fléchie(c’est-à-dire pour chaque entrée). La liste de mots communsde l’ABU est historique-ment le premier lexique flexionnel du français disponible gratuitement sur le Web.

Nom. Liste de mots communs

Adresse. Ce lexique est téléchargeable en 26 fichiers, un pour chaque lettre del’alphabet à l’adresse :

http://abu.cnam.fr/DICO/donner-dico-uncompress.html

Echantillon. Le mot lessivedispose dans cette liste des deux entrées de la fi-gure 1.7.

44. http://www.gnu.org/licenses/gpl.html .

Page 57: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Données 65

lessive lessive Nom:Fem+SGlessive lessiver Ver:IPre+SG+P1:IPre+SG+P3:SPre+SG+P1 :SPre+SG+P3:

ImPre+SG+P2

Figure 1.7. Les entrées delessivedans la liste des mots communs de l’ABU

Contenu. La liste des mots communs décrit 60 000 lemmes et 290 000 formes flé-chies différentes. Les lemmes sont les formes de citation des lexèmes : la forme àl’infinitif pour les verbes, la forme au masculin singulier pour les adjectifs ou les dé-terminants, la forme au singulier pour les noms ou les pronoms. Les lemmes sontégalement appeléstypes. La liste des mots communs de l’ABU offre une bonne cou-verture du français commun, même si certains mots courants comme les formes avecune élision (d’, l’ ou jusqu’) en sont absents.

Format. Ce lexique a un formattabulé. Chacune de ses lignes correspond à uneentrée et contient trois informations séparées par des tabulations45: le mot (la formefléchie) ; son lemme (la forme de citation du lexème) ; la catégorie du lexème complé-tée par une liste des traits morphosyntaxiques possibles pour la forme. Les élémentsdu 3e champ sont séparés par des deux-points (: ).

Ainsi, la première ligne de l’échantillon indique quelessiveest une forme au fé-minin singulier (Fem+SG) du nom (Nom) lessive. La deuxième indique quelessiveestune forme du verbe (Ver ) lessiverau présent de l’indicatif, 1re et 3e personnes du sin-gulier (IPre+SG+P1 et IPre+SG+P3 ), au présent du subjonctif, 1re et 3e personnesdu singulier (SPre+SG+P1 et SPre+SG+P3) et au présent de l’impératif, 2e personnedu singulier (ImPre+SG+P2).

Quelques entrées de ce lexique comportent malheureusementdes informationsgrammaticales mal formatées.

Licence. La liste des mots communs de l’ABU a la même licence d’utilisation queles textes (voir paragraphe 1.5.1.4).

1.5.2.3. Morphalou

Une troisième ressource lexicale gratuite, beaucoup plus complète, est le lexiquemorphologiqueMorphaloudéveloppé par l’ATILF et diffusé par le CNRTL (voir pa-ragraphe 1.5.1.2). Sa version stable actuelle est la 1.0.146.

45. La tabulation est un caractère d’espacement qui, à l’affichage, occupe une place variablepermettant un alignement en colonnes.46. La version 2.0 deMorphalouest plus riche et nettement plus complexe que la 1.0.1.

Page 58: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

66 Perl pour les linguistes

Nom. Morphalou

Adresse. http://www.cnrtl.fr/morphalou/

Echantillon. Les formes du nomlessivesont par exemple décrites de la manièresuivante dans le lexiqueMorphalou:

<lexicalEntry lemma="lessive" grammaticalCategory="co mmonNoun"grammaticalGender="feminine">

<inflectionGroup><inflection orthography="lessive"

grammaticalNumber="singular"/><inflection orthography="lessives"

grammaticalNumber="plural"/></inflectionGroup>

</lexicalEntry>

Figure 1.8. L’entrée du nomlessivedansMorphalou

Contenu. La version 1.0.1 deMorphaloucomporte 67 376 entrées (lexèmes) et524 725 formes fléchies. Les entrées correspondent à celles du Trésor de la languefrançaise. Morphalouest donc un lexique très complet. Sa qualité est nettement su-périeure à celle de la liste de mots communs de l’ABU. Il comporte une liste de motsgrammaticaux mais ces derniers ne sont pas caractérisés du point de vue morphosyn-taxique.

Format. Morphalouest au format XML ; toutes les informations y sont décritesdans des balises47 (voir chapitre 9). Les noms des balises et des valeurs sont enanglais.

On voit sur l’exemple ci-dessus que les informations relatives à une forme donnéesont distribuées dans différentes balises :

– le lemme, la catégorie et le genre se trouvent au niveau de l’en-trée (lexicalEntry ) respectivement comme valeurs des attributslemma,grammaticalCategory etgrammaticalGender ;

– la forme fléchie et le nombre sont donnés dans la baliseinflexion commevaleurs des attributsorthography et grammaticalNumber .

La répartition des informations est par ailleurs différente pour chaque catégorie. Parexemple, le genre est indiqué dans la baliseinflexion pour les adjectifs. Les pa-ragraphes 9.1.2.2 (page 324) et 9.2.2.1 (page 333) présentent de façon détaillée lecontenu de ces entrées et la manière dont on peut les manipuler.

47. Dans la version 2.0, les descriptions lexicales sont fournies dans le texte du document etnon plus indiquées dans les attributs des balises.

Page 59: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Données 67

Licence. Morphalouest distribué sous une licence spécifique qui autorise son uti-lisation à des fins de recherche mais ne permet ni sa modification, ni sa redistribution.

1.5.2.4. Lefff

Un quatrième lexique du français comportant des descriptions morphosyntaxiquesest Lefff (pourLexique des formes fléchies du Français), réalisé et diffusé par l’INRIA(institut de recherche en informatique et en automatique).

Nom. Lefff

Adresse. http://www.lefff.net/

Echantillon. Voici à titre d’exemple, les entrées de la formelessivedans la version2.1 de Lefff :

lessive nc [pred=’lessive_____1<suj:(sn),objde:(de-sn |de-sinf),obja:(à-sinf)>’,cat=nc,@fs]

lessive v [pred=’lessiver_____1<suj:sn|sinf|scompl,ob j:(sn)>’,cat=v, @imperative,@Y2s]

lessive v [pred=’lessiver_____1<suj:sn|sinf|scompl,ob j:(sn)>’,cat=v,@PS13s]

Figure 1.9. Les entrées du motlessivedansLefff

Contenu. La version 2.1 du lexique Lefff contient 504 180 entrées, plus de 105 538lemmes et de 404 634 formes fléchies. En plus des mots communs du français, celexique dispose d’un ensemble important de locutions ainsique d’une liste de nomspropres, essentiellement des prénoms et des toponymes.

Format. Lefff se présente sous un format tabulé. Chaque ligne correspond àuneentrée, et en fournit la forme fléchie, la partie du discours (nom commun (nc ), verbe(v),...), le lemme, un cadre de sous-catégorisation et un ensemble d’autres propriétéssyntaxiques et morphosyntaxiques. Par exemple, le code@PS13sde la troisième en-trée décrit les 4 valeurs de temps et de personne pour l’indicatif et le subjonctif (Ppour présent de l’indicatif,S pour présent du subjonctif,1 pour 1re personne,3 pour3e personne,s pour singulier). On voit dans cet extrait qu’il y a deux entrées séparéespour les formes verbaleslessive, l’une pour le présent de l’impératif et l’autre pour lesquatre valeurs de l’indicatif et du subjonctif. Ces deux entrées diffèrent en effet par unde leurs traits et ne peuvent donc être fusionnées (la première a un trait@imperative ,mais pas la seconde). Une documentation complète du format est disponible sur le siteWeb de Lefff.

Licence. Lefff est distribué par l’INRIA sous licence LGPLLR (Lesser GeneralPublic Licence for Linguistic Resources) qui autorise l’utilisation de cette ressourcepour la recherche et l’enseignement.

Page 60: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

68 Perl pour les linguistes

1.5.2.5. Lexique 3

Morphalouet Lefff sont clairement conçus pour la linguistique informatique.LabaseLexique 3diffusée par l’université Paris 5 est pour sa part destinée àla psycho-linguistique. Elle fournit en effet un ensemble d’informations utiles pour construire dumatériel expérimental, par exemple pour des expériences dedécision lexicale.

Nom. Lexique 3

Adresse. http://www.lexique.org/

Echantillon. Les entrées suivantes deLexique 3décrivent la formelessive:

lessive lesiv lessive NOM f s 8.98 8.78 8.86 7.70 2 4 17 5 CVCCVCV CVCVC 2 1 7 5 le-siv 2 CV-CVC evisselvisel les-si-ve NOM,VER

lessive lesiv lessiver VER 1.99 3.31 0.24 0.07 imp:pre:2s;ind:pre:3s; 2 4 0 7 5 CVCCVCV CVCVC 2 1 7 5 le-siv 2

CV-CVC evissel visel les-si-ve NOM,VER

Figure 1.10.Les entrées du motlessivedansLexique 3

Contenu. Lexique 3contient environ 135 000 formes fléchies pour 55 000 lemmes.Les descriptions phonologiques et les informations relatives à la fréquence, aux ho-mographes ou aux homophones constituent l’apport principal deLexique 3. C’est uneressource importante non seulement pour la psycholinguistique, mais aussi pour les re-cherches dans d’autres domaines comme la morphophonologie48. Cependant, contrai-rement aux lexiques destinés à la linguistique informatique,Lexique 3ne contient pasles conjugaisons complètes de tous les verbes ni toutes les formes fléchies des autreslemmes. Il n’y a par exemple que 12 entrées pour le verbelessiveralors queMorpha-lou en contient 51.

Format. Les entrées deLexique 3comportent 28 champs séparés par des tabu-lations. Parmi les nombreuses informations associées à chaque forme, signalons lareprésentation phonologique en colonne 2, le lemme en colonne 3 et la catégorie en4. Les 5e et 6e colonnes contiennent le genre et le nombre, la 11e les traits morpho-syntaxiques pour les verbes. Les colonnes 23 et 26 donnent respectivement la formeet la structure phonologique syllabées. On peut voir dans l’entrée verbale (c’est-à-direla deuxième entrée dans l’exemple ci-dessus) qu’il manque les informations relativesà la 1re personne du singulier et au subjonctif.

48. Il existe des lexiques phonologiques beaucoup plus complets que l’on trouve notammentsur le catalogue de l’ELRA (http://www.elra.info ).

Page 61: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Données 69

Licence. Lexique 3est diffusé sous une licence spécifique de type GPL (Licencepublique générale pour les bases de données) qui autorise son utilisation pour la re-cherche et l’enseignement.

1.5.2.6.Verbaction

Verbactionest un lexique de noms d’actions morphologiquement apparentés à desverbes distribué par le laboratoire CLLE-ERSS (CNRS et université de Toulouse leMirail).

Nom. Verbaction

Adresse. http://w3.univ-tlse2.fr/erss/ressources/verbaction/

Echantillon. Les entrées pour le verbelessiverdans la version tabulée deVerbac-tion sont :

lessiver/Vmn---- lessivage/Ncmslessiver/Vmn---- lessivement/Ncmslessiver/Vmn---- lessive/Ncfs

Figure 1.11.Les entrées delessiverdans Verbaction

Contenu. Verbactionest composé de 9 393 couples verbe:nom tels que :

– le nom est morphologiquement apparenté au verbe ;

– le nom peut être utilisé pour dénoter l’action ou l’activité exprimée par le verbe.

Format. Ce lexique est disponible aux formats XML et tabulé. Dans la versiontabulée, chaque entrée décrit un couple verbe:nom au moyen de lemmes munisde catégories et de descriptions morphosyntaxiques au format GRACE (voir para-graphe 1.5.2.8) :Vmn---- pour les verbes,Ncmspour les noms masculins singuliers,Ncfs pour les féminins singuliers,Ncmppour les masculins pluriels etNcfp pour lesféminins pluriels. La forme du lemme est séparée de la catégorie par une barre oblique(/ ).

Licence. Verbactionest diffusé sous licenceCreative Commons49 qui en autorisel’exploitation, la modification et la diffusion non commerciale.

1.5.2.7.Ressources lexicales redistribuées dans l’environnementde travail

L’environnement de travail mis à disposition sur le site d’accompagnement du livre(voir section 2.1) contient cinq ressources lexicales :

49. http://creativecommons.org/licenses/by-nc-sa/2.0/fr / .

Page 62: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

70 Perl pour les linguistes

– la liste de motdico, proposé dans une version normalisée, c’est-à-dire avec deslettres accentuées notées de façon usuelle ;

– la liste des mots communs de l’ABU ;

– le lexique Lefff ;

– la base de donnéesLexique 3;

– le lexiqueVerbaction, fourni aux formats XML et tabulé.

Lefff est proposé dans sa forme originale et dans une version simplifiée qui necontient ni les noms propres ni les mots grammaticaux. Dans cette seconde version,les descriptions morphosyntaxiques sont traduites dans leformat GRACE qui est pré-senté ci-dessous. L’environnement de travail contient le programme Perllefff2grace.plqui permet de créer la version simplifiée à partir de la version originale. Un programmesimilairemorphalou2grace.plest fourni pour la conversion deMorphalouau formatGRACE. La création de cette version deMorphalouà partir de la ressource téléchar-gée est décrite en détails au paragraphe 2.7.7 (page 110). Laconversion de ces deuxlexiques dans un format identique permet de les utiliser conjointement mais aussi deles manipuler au moyen des mêmes programmes (voir chapitre 8).

1.5.2.8.Le format lexical GRACE

lessiva lessiver Vmis3s-lessivage lessivage Ncmslessivages lessivage Ncmplessivai lessiver Vmis1s-lessivaient lessiver Vmii3p-lessivais lessiver Vmii1s-lessivais lessiver Vmii2s-lessivait lessiver Vmii3s-lessiver lessiver Vmn----[...]lexical lexical Afpmslexicale lexical Afpfslexicales lexical Afpfp

Figure 1.12.Extrait du lexiqueMorphaloutraduit dans le format GRACE

Les sections qui précèdent illustrent la variété des formats des ressources lexicales.Cette fluctuation empêche d’utiliser le même programme avecdes lexiques différents.Une solution à cette difficulté consiste à traduire dans un même format simple lesdifférents lexiques que l’on souhaite utiliser, en l’occurrence les deux plus importants :Morphalouet Lefff. Le format choisi est celui de la campagne d’évaluation GRACE50.

50. Grammaires et ressources pour les analyseurs de corpus et leur évaluation, voirhttp://www.limsi.fr/TLP/grace/ .

Page 63: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Données 71

Il s’agit d’un format tabulé dont chaque entrée contient uneforme, son lemme et unecatégorie complétée de traits morphosyntaxiques. La figure1.12 présente quelquesentrées extraites de la version au format GRACE deMorphalou.

Comme le montre cet échantillon, les descriptions morphosyntaxiques comportentune catégorie codée par le premier caractère en majuscule (N pour nom,V pourverbe,A pour adjectif,R pour adverbes). Les traits morphosyntaxiques sont décritspar une séquence de caractères dont la taille est fixe pour chaque catégorie (3 pourles noms, 6 pour les verbes, 4 pour les adjectifs, 2 pour les adverbes). La significa-tion de chaque caractère de la séquence dépend de sa position. Les tableaux suivantsprésentent ces traits et leurs valeurs possibles pour les 4 catégories majeures (voirhttp://www.limsi.fr/TLP/grace/ pour une description complète du jeu d’éti-quettes GRACE).

catégorieN nom

type c commungenre f féminin

m masculinnombre p pluriel

s singulier

Par exemple, l’étiquette d’un nom commun masculin singulier estNcms. CommeMorphalouet la version simplifiée de Lefff ne contiennent que des noms communs,les étiquettes nominales de ces lexiques ont donc toutes le typecommun. En d’autrestermes, elles commencent toutes parNc.

catégorieA adjectif

type f qualificatifdegré p positifgenre f féminin

m masculinnombre p pluriel

s singulier

Là encore, les traits de type et de degré ont des valeurs constantesqualificatif pourle premier etpositif pour le second car les lexiquesMorphalouou Lefff ne distinguentni les différents types d’adjectifs (qualificatifs, ordinaux, cardinaux, indéfinis ou pos-sessifs) ni les comparatifs. Les étiquettes des adjectifs commencent donc toutes parAfp . Par exemple, celle d’un adjectif féminin pluriel estAfpfp .

Page 64: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

72 Perl pour les linguistes

catégorieV verbe

type m principalmode c conditionnel

i indicatifm impératifn infinitifp participes subjonctif

temps f futuri imparfaitp présents passé

personne1 1re personne2 2e personne3 3e personne

nombre p pluriels singulier

genre f fémininm masculin

Les lexiques de départ ne distinguent pas non plus les auxiliaires des autres verbes.De ce fait, le trait de type est aussi constant pour les verbes. Par ailleurs, tous les traitsne sont pas définis pour toutes les formes verbales. Par exemple, le genre ne l’est paspour la formebavardani le temps, la personne, le nombre et le genre pour l’infinitiflessiver. L’absence de valeur pour un trait donné est indiquée par un tiret dans laposition correspondante. Ainsi,lessivaa l’étiquetteVmis3s- quand c’est une formeà l’indicatif passé simple 3e personne du singulier. L’infinitiflessivera quant à luil’étiquetteVmn---- .

catégorieR adverbe

type g généraldegré p positif

Comme pour les adjectifs et pour les mêmes raisons, les traits de type et de genredes adverbes sont constants. Il n’y a donc qu’une seule étiquette pour les adverbes :Rgp.

1.6. Obtenir une ressource

1.6.1. Identifier et localiser les ressources à utiliser

Comme on l’a vu dans les inventaires précédents, les ressources utilisables pourdes recherches en linguistique sont nombreuses et dispersées. Certaines organisations

Page 65: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Données 73

comme la liste de diffusionLinguistList51 ou la bibliothèque virtuelle de l’Ecole nor-male supérieure lettres et sciences humaines52proposent des répertoires de ressourcesutiles pour les recherches sur les langues et le langage.

Les moteurs de recherche permettent en général de trouver facilement sur le Webles ressources que l’on a identifiées : les centres de recherche qui les mettent à dispo-sition y sont référencés. Rappelons à nouveau qu’il est impératif de prendre connais-sance de la licence qui accompagne les ressources avant toute utilisation.

1.6.2. Télécharger des documents en grand nombre

Les programmes présentés dans cet ouvrage, à l’exception deceux du chapitre 10,sont conçus pour traiter des données qui se trouvent sur l’ordinateur sur lequel ils sontexécutés. Ces données doivent être téléchargées, c’est-à-dire copiées sur l’ordinateurde l’utilisateur. Leur téléchargement peut être réalisé aumoyen d’un navigateur, enutilisant par exemple les menus contextuels : clic droit puisEnregistrer la cible du liensous...avecFirefox ; clic droit puisEnregistrer la cible sous...avecInternet Explorer(voir paragraphe 1.4.2.4). Ce mode de téléchargement convient pour les ressourcescomposées d’un petit nombre de fichiers ou éventuellement d’un seul, notammentde celles qui sont destinées à la linguistique informatique(par exemple le corpus duCNRTL, voir paragraphe 1.5.1.2). Pour d’autres, comme les corpus des bibliothèquesvirtuelles ou les sites Web spécialisés, ce type de téléchargement en bloc n’est pasdisponible. On peut cependant dans certains cas faire appelà des utilitaires d’aspi-ration de sites Web commeHTTrack53 ou wget54. Ces logiciels permettent de créerune copie locale d’un document, d’un fragment de site Web ou d’un site complet. Leprincipe de fonctionnement de ces outils est simple : l’aspirateur part d’une adresseWeb donnée (c’est-à-dire une URL) ; il télécharge la page correspondante ; s’il s’agitd’un document HTML, il analyse son contenu pour en extraire les liens (c’est-à-direles renvois vers d’autres pages Web) ; il répète ensuite l’opération sur chacune desadresses de page ainsi collectées.

Les deux outils,HTTrack etwget, possèdent des options très nombreuses qui per-mettent de contrôler finement leur fonctionnement.HTTrack est un programme dis-ponible sous Windows et sous Unix qui dispose d’interfaces utilisateurs pour les deux

51. http://www.linguistlist.org/ .52. http://cid.ens-lsh.fr/bibvir/ .53. http://www.httrack.com/ .54. Ce programme fait partie du paquetageUnxUtils :http://unxutils.sourceforge.net/ .Une copie de ce paquetage est incluse dans l’environnement de travail mis à disposition sur lesite d’accompagnement du livre.

Page 66: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

74 Perl pour les linguistes

systèmes (WinHTTracketWebHTTrack55 respectivement). Ces interfaces servent es-sentiellement à préciser les valeurs des nombreux paramètres de la commande : nomde projet ; répertoire de destination ; adresse Web de départ; type de téléchargement,etc.

Unix. wget est un programme disponible sous Unix et sous Windows que l’oninvoque dans un terminal. Son intérêt principal est qu’une fois lancé, il n’interagitplus avec l’utilisateur. Pour aspirer la partie d’un site qui se trouve sous une URLdonnée,wget peut être appelé de la manière suivante :

wget -m -L -np URL

La commandewgetest utilisée ici avec trois options. La première,-m pourmirror,indique que l’on souhaite créer une copie du site. La deuxième option-L , indiquequ’on ne s’intéresse qu’aux liens relatifs, c’est-à-dire qui sont identifiés par un cheminrelatif et non par une URL complète (voir paragraphe 2.4.3).On est ainsi assuré dene pas récupérer de pages qui se trouveraient sur d’autres sites. La dernière option-np (pourno parent) précise que la copie est limitée à la partie du site qui se trouvesousURL. Les liens qui remontent vers les parents (les pages situéesplus haut dansl’arborescence) sont ignorés.

wget peut aussi être utilisé pour télécharger uniquement des fichiers d’un formatdonné. On peut par exemple obtenir une copie de l’ensemble des documents au formatPDF qui composent la Bibliothèque électronique duQuébec56 au moyen de la simplecommande suivante :

wget -r -l inf -L -np -A.pdf http://jydupuis.apinc.org/ind ex2.htm

Les options utilisées sont :-r pour demander que le télécharge-ment soit récursif, c’est-à-dire qu’il concerne aussi les sous-répertoires dehttp://jydupuis.apinc.org/ ; -l inf pour indiquer que la profondeurde la récursion peut être infinie ;-L et -np qui ont déjà été présentées ;-A.pdf

pour limiter le téléchargement aux seuls fichiers dont l’extension est.pdf . Cettecommande crée dans le répertoire dans lequel elle est lancéeune copie 1) de lastructure arborescente du site ; 2) des fichiers PDF qui s’y trouvent.

L’utilisation d’un aspirateur de site Web ne permet pas toujours de copier complè-tement le site identifié par une URL. Il y a essentiellement deux causes aux échecs :

55. Cette interface nécessite la présence sur le système d’un serveur Web et d’un interpréteurPHP.56. http://jydupuis.apinc.org/ .

Page 67: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Données 75

1) l’interdiction explicite sur le site Web d’accéder par detels outils à tout ou partiedes pages hébergées. Les outils d’aspiration de site Web, etnotammentHTTrack etwget, respectent ces interdictions ;

2) la représentation des liens hypertextes sous des formes complexes (comme lesprogrammes en javascript). Les aspirateurs de sites sont alors bloqués car ils sontincapables d’identifier les pages ainsi cachées.

Il faut cependant savoir que les institutions ou les personnes qui distribuent desressources pour la recherche proposent généralement un accès aisé à ces dernièreset que les ressources les plus difficiles à télécharger sont normalement celles dontl’utilisation est la plus contrainte.

1.7. Segmentation, catégorisation et lemmatisation des textes

Les ressources textuelles, qu’elles soient acquises auprès de distributeurs ou misesà disposition par des organismes ou des associations, ne sont généralement pas « prêtesà l’emploi ». Il faut souvent réaliser sur ces ressources différentes préparations préa-lables à leur utilisation effective comme la conversion au format texte (voir para-graphe 1.4.2), la conversion dans un codage approprié (voirannexe A2), la suppressiondes entêtes (voir section A1.3, page 405), la segmentation en mots, la catégorisation,la lemmatisation.

Nous présentons dans cette section les trois dernières opérations. Les différentestechniques d’exploitation présentées dans cet ouvrage s’appliqueront en effet aux ré-sultats de ces traitements fondamentaux.

1.7.1. Segmentation

La segmentation d’un texte en mots consiste à identifier les mots qui le composentet à les présenter sous une forme verticale, où chaque mot estécrit sur une ligneséparée. Par exemple, la segmentation en mots du premier paragraphe de la figure 1.4(Je m’étais pris d’une profonde sympathie pour ce grand flemmard de gabelou[...], mais de la bonne douane flâneuse et contemplative des falaises et des grèves.) estprésentée en figure 1.13, page 76.

Cette opération (réalisée automatiquement par des programmes dédiés) permetde faciliter l’exploitation des textes, notamment pour y repérer automatiquement desformes lexicales (voir chapitre 5) ou effectuer des mesuressur le vocabulaire d’untexte (voir chapitre 6).

Page 68: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

76 Perl pour les linguistes

Jem’étaisprisd’uneprofondesympathiepourcegrandflemmarddegabelou[...]

,maisdelabonnedouaneflâneuseetcontemplativedesfalaisesetdesgrèves.

Figure 1.13.Exemple de texte segmenté en mots

Le découpage du texte en mots s’appuie sur l’approximation qu’un mot est uneséquence de lettres entourée par des délimiteurs comme les espaces, les fins de ligne,les signes de ponctuation, les parenthèses, etc. La principale difficulté que pose cetteopération vient de l’ambiguïté de certains caractères comme l’apostrophe, le tiret oule point :

– l’apostrophe doit donner lieu à une coupure dansl’homme→ l’ ‖ hommemaispas dansaujourd’hui→ aujourd’huiouhors-d’œuvre→ hors-d’œuvre;

– le tiret doit être détaché danspensez-vous→ pensez‖ -vousmais pas dans unelocution adverbiale commevice-versa→ vice-versa;

– le point peut être une marque de fin de phrase comme dansIl dort.→ Il ‖ dort ‖ .ou une marque d’abréviation dansle Pr. Henry→ ; le ‖ Pr. ‖ HenryouMM. Martin etBernard→MM. ‖Martin ‖ et ‖ Bernard.

Ces problèmes sont résolus au moyen de listes d’abréviations et de formes polylexi-cales. La segmentation en mots est présentée en détail en section A1.2, page 396.

Il est enfin important de noter que cette opération n’est pas réversible, puisqu’ellene permet pas de préserver le peu de mise en page autorisée dans un format texte,notamment la délimitation des paragraphes (la fin de ligne étant devenue un simpleséparateur de mots).

1.7.2. Catégorisation et lemmatisation

Un grand nombre d’expériences ne peuvent pas être réaliséessur des textes brutsou simplement segmentés en mots mais nécessitent des textescatégorisés. La catégo-risation (on parle également d’étiquetage) d’un texte consiste à munir chaque mot de

Page 69: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Données 77

sa catégorie (c’est-à-dire de la partie du discours à laquelle il appartient) et des traitsmorphosyntaxiques pertinents comme le genre et le nombre pour les noms ou le tempset la personne pour les verbes conjugués. Ces informations sont associées aux motsdu texte sous forme d’étiquettes morphosyntaxiques (similaires à celles utilisées dansles lexiques). En plus de la catégorie, les catégoriseurs fournissent aussi un lemmepour chaque mot. Ces deux opérations, réalisées automatiquement par le même typed’outils, s’accompagnent systématiquement d’une segmentation préalable en mots, etle résultat en est présenté sous un format vertical. Voici par exemple le résultat del’étiquetage par leTreeTagger57 de l’extrait utilisé ci-dessus :

Je PRO:PER jem’ PRO:PER meétais VER:impf êtrepris VER:pper prendred’ PRP deune DET:ART unprofonde ADJ profondsympathie NOM sympathiepour PRP pource PRO:DEM cegrand ADJ grandflemmard NOM flemmardde PRP degabelou NOM gabelou

, PUN ,mais KON maisde PRP dela DET:ART lebonne ADJ bondouane NOM douaneflâneuse ADJ flâneuret KON etcontemplative ADJ contemplatifdes PRP:det dufalaises NOM falaiseet KON etdes PRP:det dugrèves NOM grève. SENT .

Figure 1.14.Exemple de texte catégorisé par leTreeTagger

Le résultat de la catégorisation est un fichier texte au format tabulé dans lequel chaquemot est représenté sur une ligne qui contient la forme de surface suivie de sa caté-gorie (2e colonne) puis de son lemme (3e colonne). On voit sur cet extrait que lesétiquettes duTreeTaggersont essentiellement limitées à la catégorie (excepté pourlesverbes), les traits morphosyntaxiques étant en effet difficiles à déterminer automati-quement. D’autres catégoriseurs utilisent des jeux d’étiquettes58 plus riches.CordialAnalyseur59, développé par la société Synapse Développement, fournit par exempledes descriptions morphosyntaxiques complètes (le lemme apparaît dans la 2e colonneet la catégorie dans la 3e, au format GRACE) :

57. http://www.ims.uni-stuttgart.de/projekte/corplex/Tr eeTagger/ .58. On appellejeu d’étiquettes, l’ensemble des catégories éventuellement munies de traits mor-phosyntaxiques utilisées par un catégoriseur.59. http://www.synapse-fr.com/ .

Page 70: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

78 Perl pour les linguistes

==== DEBUT DE PHRASE ====Je je Pp1.snm’ me Pp1.s-étais être Vaii1spris prendre Vmpasmd’ de Spune un Da-fs-iprofonde profond Afpfssympathie sympathie Ncfspour pour Spce ce Dd-ms-grand grand Afpmsflemmard flemmard Ncmsde de Spgabelou gabelou Ncms

, , Ypmais mais Ccde de Spla le Da-fs-dbonne bon Afpfsdouane douane Ncfsflâneuse flâneur Afpfset et Cccontemplative contemplatif Afpfsdes de Da-.p-ifalaises falaise Ncfpet et Ccdes de Da-.p-igrèves grève Ncfp. . Yp

===== FIN DE PHRASE =====

Figure 1.15.Exemple de texte catégorisé parCordial Analyseur

Les procédures automatiques qui effectuent ces opérationsne garantissent pas unrésultat irréprochable. Des erreurs sont à envisager, notamment lorsque les mots ren-contrés sont rares, mal orthographiés, ambigus, ou apparaissent dans des structuressyntaxiques complexes. Toutefois, l’utilité de ces informations obtenues à peu de fraiscontrebalance amplement ces erreurs ou imprécisions, surtout lorsque l’on a affaire àdes données volumineuses.

1.7.3. TreeTagger

Dans la suite de l’ouvrage nous ne considérons que des textescatégorisés par leTreeTagger. Ce dernier, réalisé et distribué par l’université de Stuttgart, présente plu-sieurs avantages : il fonctionne à la fois sous Windows et sous Unix60; ses résultatssont de qualité satisfaisante ; il est rapide et permet de catégoriser des fichiers vo-lumineux ; il est diffusé gratuitement. Notons qu’il peut également être utilisé pourcatégoriser des textes dans d’autres langues que le français (voir le site deTreeTaggerpour plus de détails).

Le TreeTaggerréalise trois opérations lorsqu’il catégorise un texte : 1)il le seg-mente en mots ; 2) il détermine la catégorie de chaque mot ; 3) il calcule son lemme.

60. La catégorisation est identique sous les deux systèmes. Lasegmentation des textes présentecependant de légères différences.

Page 71: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Données 79

Segmentation. Sous Windows, le module de segmentation duTreeTaggerest sen-sible à la présence ou l’absence d’espaces devant ou derrière les apostrophes, les vir-gules ou les points. Il est recommandé de ne pas détacher les mots dans les textes avantde les étiqueter.

Le TreeTaggerest livré avec une petite liste d’exceptions (dans le fichiertextefrench-abbreviations). Elle peut être complétée en fonction des erreurs de segmenta-tion rencontrées.

Catégorisation. Une fois les unités du texte identifiées, leTreeTaggerdéterminela catégorie de chacune d’elles en fonction de son lexique etdes procédures dedésambiguïsation qu’il implémente. Le jeu d’étiquettes utilisé est le suivant :

Etiquette SignificationABR abréviationADJ adjectifADV adverbeDET:ART articleDET:POS possessif (ma, ta, ...)INT interjectionKON conjonctionNAM nom propreNOM nomNUM numéralPRO pronomPRO:DEM pronom ou déterminant démonstratifPRO:IND pronom indéfiniPRO:PER pronom personnelPRO:POS pronom possessif (mien, tien, ...)PRO:REL pronom relatifPRP prépositionPRP:det préposition contractée (au, du, aux, des)PUN ponctuationPUN:cit ponctuation de citation (guillemets)SENT fin de phraseSYM symboleVER:cond verbe au conditionnelVER:futu verbe au futurVER:impe verbe à l’impératifVER:impf verbe à l’imparfaitVER:infi verbe infinitifVER:pper participe passéVER:ppre participe présent

Page 72: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

80 Perl pour les linguistes

Etiquette SignificationVER:pres verbe au présentVER:simp verbe au passé simpleVER:subi verbe à l’imparfait du subjonctifVER:subp verbe au présent du subjonctif

Ces étiquettes sont moins fines que celles d’autres catégoriseurs, mais elles sontlargement suffisantes pour la plupart des utilisations. On peut noter que les tempsverbaux composés sont absents de cette liste car la catégorisation est réalisée au niveaudes mots. LeTreeTaggerest relativement fiable même s’il commet régulièrement deserreurs sur les mots grammaticaux ambigus commeaucun, tout ou tant. C’est en faitle cas de tous les catégoriseurs.

Lemmatisation. Le TreeTaggerpropose 2 modes de lemmatisation. Dans le pre-mier qui est le mode par défaut sous Linux, seules les formes qui appartiennent àson lexique sont lemmatisées. Toutes les autres reçoivent la valeur<unknown> quiindique que le lemme correspondant est inconnu. C’est le caspour l’extrait suivantdeA se tordre: [...] une affection que je diagnostiquai : crapulite pochardoïde et va-drouilliforme., puisque les trois formescrapulite, pochardoïdeetvadrouilliformesontdes créations de l’auteur.

une DET:ART unaffection NOM affectionque PRO:REL queje PRO:PER jediagnostiquai VER:simp diagnostiquer: PUN :crapulite NOM <unknown>pochardoïde ADJ <unknown>et KON etvadrouilliforme ADJ <unknown>. SENT .

Figure 1.16.Exemple de lemmes inconnus duTreeTagger

Comme on le voit, les catégories des mots inconnus n’en sont pas moins correcte-ment attribuées, mais cela n’est pas systématiquement le cas.

Lorsque leTreeTaggerest invoqué avec l’option-no-unkownqui correspond aumode par défaut sous Windows, le lemme n’est plus<unknown>mais la forme elle-même, sans aucune modification. Cette option n’affecte pas la catégorisation.

De nombreux mots sont au final inconnus duTreeTaggeren plus des créationsd’auteurs : les mots mal orthographiés, dans une autre langue que le français, relevantd’un vocabulaire spécialisé ou récemment apparus.

Page 73: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Données 81

La lemmatisation duTreeTaggerest une simple projection lexicale. Aucune désa-mbiguïsation n’est réalisée. Si la forme et la catégorie ne permettent pas d’identifierun lemme unique, leTreeTaggerfournit toutes les réponses possibles comme pour lesmots suivants :

accrue VER:pper accroire|accroîtrearrivée NOM arrivé|arrivéeconvient VER:pres convenir|conviercours NOM cour|coursdouteuse ADJ douteur|douteuxfils NOM fil|filsfois NOM foi|foisles PRO:PER la|lemois NOM moi|moisouvre VER:pres ouvrer|ouvrirsens NOM sen|senssuis VER:pres suivre|êtresommes VER:pres sommer|être

Figure 1.17.Exemple de formes ayant une lemmatisation ambiguë

Lors de l’exploitation des textes catégorisés par leTreeTagger, il faut donc prendreen compte la possibilité que les lemmes soient ambigus. Par exemple, une personnequi souhaite étudier les temps composés formés avec l’auxiliaireêtredoit prévoir quepour les premières personnes du singulier et du pluriel la valeur du lemme n’est pasêtre mais respectivementêtre|suivre etêtre|sommer .

Une solution moins coûteuse consiste à effectuer une désambiguïsation de la lem-matisation duTreeTagger, par exemple en utilisant le lemmatiseur FLEMM61 déve-loppé par Fiammetta Namer. Il est aussi possible de désambiguïser très sommairementces lemmatisations en sélectionnant pour toutes les occurrences l’une des options :suisaurait alors le lemmeêtre et convientle lemmeconvenir . Cette désambiguïsationne génère que peu d’erreurs. Elle est réalisée par le programme desambiguisation-lemmatisation.plprésenté en section A1.4, page 406.

L’environnement de travail fournit deux commandes de lancement duTreeTag-ger (tag-french-desambsous Windows ettree-tagger-french-desambsous Unix) quiintègrent l’appel au programmedesambiguisation-lemmatisation.pl. Ces commandespermettent d’autre part d’uniformiser le traitement des lemmes inconnus sur les deuxsystèmes.

61. http://www.univ-nancy2.fr/pers/namer/Telecharger_Fl emm.htm.

Page 74: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

82 Perl pour les linguistes

Installation et utilisation. Le paragraphe 2.7.6 du chapitre suivant détaille les opé-rations nécessaires à l’installation duTreeTaggersur un système de type Windows ouUnix.

Comme ce catégoriseur ne dispose pas d’une interface graphique, il ne peut êtreinvoqué que dans un terminal (voir paragraphe 2.3.1, page 89). L’étiquetage d’un textecontenu dans un fichierfichier.txt se fait de la manière suivante :

1) se placer dans le répertoire dans lequel se trouve le texteen utilisant la com-mandecd (voir paragraphe 2.4.4, page 94) ;

2) exécuter la commande :

Windows. tag-french fichier.txt > fichier.tt

ou tag-french-desamb fichier.txt > fichier.tag

Unix. tree-tagger-french fichier.txt > fichier.tt

ou tree-tagger-french-desamb fichier.txt > fichier.tag

Le chapitre suivant explique pas à pas les différentes notions nécessaires pour in-teragir avec le système d’exploitation et effectuer des opérations comme celles-ci.

Page 75: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

CHAPITRE 2

Environnement de travailet notions de système

Ce chapitre est consacré à la mise en place de l’environnement de travail et auxnotions de système d’exploitation nécessaires à l’exécution des programmes Perl. Ilcomprend trois parties. La section 2.1 décrit l’installation de la partie de l’environne-ment de travail qui est distribuée sur le site d’accompagnement de l’ouvrage et cellede l’interpréteurActivePerlpour les systèmes Windows. La deuxième partie (sections2.2 à 2.6) présente les éléments de système d’exploitation nécessaires à l’exécutiondes commandes en ligne et des programmes Perl. Elle s’adresse avant tout aux per-sonnes qui travaillent sous Windows. Des indications sont néanmoins fournies pouradapter les notations aux systèmes Unix lorsque cela est pertinent. La troisième partie(section 2.7) est consacrée à l’installation d’outils et deressources supplémentaires,aux éventuelles adaptations des environnements Unix et au système d’aide en ligne dulangage Perl.

Les commandes et les programmes présentés dans ce chapitre n’ont été testés sousWindows que pour la version XP. Dans les exemples, les textessaisis par l’utilisateurau clavier sont écrits en gras.

2.1. Environnement de travail initial

Cette courte section présente en détail l’installation initiale de l’envi-ronnement de travail disponible sur le site d’accompagnement de l’ouvrage(http://perl.linguistes.free.fr/ ) et l’installation de l’interpréteurActive-Perl. L’environnement est proposé dans deux versions, l’une pour Windows et l’autre

83

Page 76: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

84 Perl pour les linguistes

pour Unix. On supposera par la suite que les utilisateurs d’Unix sont familiers avecles notions fondamentales, qui ne seront rappelées que pourle système Windows.

2.1.1. Pour Windows

La version Windows de l’environnement de travail peut être téléchargée par l’in-termédiaire d’un navigateur Web (Firefox, Internet Explorer, etc.) en cliquant sur lelien PPL pour Windowsde la pagehttp://perl.linguistes.free.fr/ . Unprogramme d’installation,PPL.exe, apparaît alors sur leBureau1. L’environnementde travail s’installe en exécutant ce programme (double-cliquer sur l’icône). Le pro-gramme s’exécute sans interaction avec l’utilisateur saufs’il existe déjà un dossierC:\PPL ou C:\SciTE. Dans ce cas, une confirmation est demandée avant de remplacerles fichiers du dossier existant par ceux de l’environnementà installer.

Une fois l’installation réalisée, l’utilisateur dispose de :

1) un dossierC:\PPL qui contient :a) un terminal préconfiguré,PPLterm, permettant notamment d’afficher cor-

rectement les résultats des programmes Perl ;b) un dossier pour chaque chapitre de l’ouvrage, rassemblant les programmes

et les fichiers utilisés dans les exemples ;c) un dossierCorpuscontenant les corpus mis à disposition (voir paragraphe

1.5.1.11) ;d) un dossierLexiquescontenant les différents lexiques mis à disposition (voir

paragraphe 1.5.2.7) ;e) un dossierUnxUtils contenant les utilitaires de cette distribution ;

2) un dossierC:\SciTE qui contient l’éditeur de texteSciTE ;

3) trois liens sur leBureau:a) un lien vers le dossierC:\PPL;b) un lien permettant de lancer le terminal préconfiguréPPLterm;c) un lien permettant de lancer l’éditeurSciTE.

Par ailleurs, le programme d’installation met à jour la variable d’environnementPATHpour que l’éditeurSciTE, le catégoriseurTreeTaggeret les autres programmesde l’environnement puissent être lancés facilement (voir section 2.7).

1. Le Bureauest la destination par défaut des fichiers téléchargés. Cependant, si le navigateurpropose de sélectionner l’endroit dans lequel le fichier doit être enregistré, indiquer leBureau,en utilisant l’icône qui se trouve dans le cadre de gauche ou le menuEnregistre dans :en hautde la fenêtre.PPL.exepeut aussi être téléchargé comme suit : 1) placer la souris sur le lien ; 2)faire apparaître le menu contextuel par un clic droit ; 3) sélectionnerEnregistre la cible du liensous...(Firefox) ouEnregistrer la cible sous...(Internet Explorer) ; 4) sélectionner leBureau.

Page 77: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Environnement de travail et notions de système 85

2.1.2. Pour Unix

La version Unix de l’environnement de travail initial,PPL.tgz, est une archivetar compressée pargzip (voir paragraphe 1.4.3). Ce fichier peut être téléchargésur la machine de l’utilisateur en cliquant sur le lienPPL pour Unix de la pagehttp://perl.linguistes.free.fr/ . Il suffit ensuite de placerPPL.tgzà l’en-droit où l’on veut installer l’environnement (par exemple dans le répertoire principalde l’utilisateur,~/ ) puis de décompresser l’archive en utilisant la commande suivante :

ident @labo:~> tar xzf PPL.tgz

où ident @labo:~> correspond à l’invite affichée par leshell. Un répertoirePPL2 estcréé à l’endroit où la commande est exécutée.

Ce répertoire contient :

1) un sous-répertoire pour chacun des chapitres de l’ouvrage. Chaque sous-répertoire rassemble les programmes et les fichiers utilisés dans le chapitre ;

2) un sous-répertoireCorpuscontenant les corpus mis à disposition (voir para-graphe 1.5.1.11) ;

3) un sous-répertoireLexiquescontenant les différents lexiques mis à disposition(voir paragraphe 1.5.2.7).

2.1.3. ActivePerl (Windows)

Le système Windows ne fournit pas, de base, un interpréteurperl. Cet outil estnécessaire au fonctionnement des programmes Perl décrits dans la suite de l’ouvrage.L’utilisateur doit en installer un lui-même. Plusieurs distributions existent mais nousconseillons d’utiliserActivePerl3 de la société ActiveState qui est gratuite et très com-plète :

1) ActivePerl peut être téléchargée en utilisant un navigateur Web, à l’URL :http://www.activestate.com/store/activeperl/downloa d/ ;

2) cliquer sur le boutonContinuer(il n’est pas nécessaire de remplir le formulaireprésenté sur la page) ;

3) télécharger la version la plus récente (5.8 ou supérieure) en formatMSI pourWindows (x86). Enregistrer l’installateur de la distributionActivePerl sur leBureau(voir note 1, page 84).

2. Si un répertoirePPL existe déjà à cet endroit, il est préférable de le renommer avant de lancerla commande. Les fichiers présents dans le répertoire existant seraient sinon remplacés par ceuxde l’archive.3. http://www.activestate.com/Products/ActivePerl/ .

Page 78: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

86 Perl pour les linguistes

On procède ensuite à l’installation du logiciel de la manière suivante :

1) double-cliquer sur l’icône de l’installateurActivePerlqui se trouve sur leBu-reau;

2) cliquer sur le boutonNext;

3) accepter le contrat de licence en cochant l’entréeI accept the terms of the Li-cence Agreement, puis cliquer à nouveau sur le boutonNext;

4) cliquer deux fois sur le boutonNextsans modifier les paramètres par défaut ;

5) cliquer sur le boutonInstall ;

6) cliquer pour finir sur le boutonFinish.

Unix. Les systèmes Unix comme Linux ou Mac OS X disposent tous d’un interpré-teurperl de base. Certains modules supplémentaires doivent cependant être installés,notamment ceux qui sont utilisés par les programmes des chapitres 9 et 10 (voir para-graphe 2.7.3).

Les trois sections qui suivent s’adressent d’abord aux personnes qui travaillentsous Windows. Elles présentent aussi, mais de façon plus sommaire, la manière dontles notions et les notations décrites doivent être adaptéesaux systèmes Unix. Lesexemples qui sont utilisés dans ces sections supposent que l’environnement de tra-vail initial est correctement installé sur la machine de l’utilisateur.

2.2. Fichiers, répertoires et volumes

Dans un ordinateur, les données et les programmes sont stockés dans desfichiersetsont manipulés par l’intermédiaire du système d’exploitation (Windows, Linux, MacOS X). Ces fichiers ne sont pas tous conservés en vrac, mais sont répartis dans desré-pertoires, oudossiersdans la terminologie Windows. Les répertoires sont des « lieux »qui ont une organisation hiérarchique arborescente : à chaque niveau de l’arbores-cence, on peut trouver des fichiers et dessous-répertoires. Par exemple, le répertoireC:\PPL peut être visualisé en double-cliquant sur le lienPPL qui se trouve sur leBu-reau. On y voit des fichiers commeLISEZMOI et des répertoires comme02.Systeme.

Les fichiers et les répertoires sont conservés sur des supports physiques que l’onappellepartitions, ouvolumesdans la terminologie Windows. Les volumes sont iden-tifiés par des lettres majuscules suivies de ‘:’ (C:, D:, E:, ...).C: est le volume principaldu système. Il correspond au disque dur sur lequel est installé le système d’exploita-tion. Les autres volumes couramment utilisés sontD: (pour le lecteur de CD et deDVD) ainsi queE: et F: pour les clés USB ou les disques externes.

Sur chaque volume, il existe un répertoire de plus haut niveau, celui qui contienttous les autres, que l’on appelle laracine ou le répertoire racine. On le note par le

Page 79: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Environnement de travail et notions de système 87

nom du volume suivi de ‘\’ (barre oblique arrière ; ce caractère peut être saisi par lacombinaison de touchesAltGr+8 ; la touche ‘8’ n’est pas celle du pavé numériquemais celle qui se permet de taper le trait bas ‘_’). Par exemple, la racine du volumeC:estC:\.

Unix. Sous Unix, les supports physiques sont vus comme des répertoires normauxque les utilisateurs n’ont ni à connaître, ni à désigner. D’autre part, un système Unixn’a pas de volumes et n’a donc qu’un seul répertoire racine ; ce dernier est noté parune barre oblique avant ‘/’.

2.2.1. Explorateur Windows

Le système Windows inclut un navigateur, appeléExplorateur Windows, qui per-met de visualiser les volumes, les répertoires et les fichiers. Il peut être lancé par lemenuDémarrer>Tous les programmes>Accessoires>Explorateur Windows.

L’ Explorateur Windowsest un outil central pour naviguer dans l’arborescence desrépertoires et pour réaliser des manipulations simples surles fichiers et les répertoires.Il permet de créer et d’afficher des répertoires, de lancer des programmes, de suppri-mer, déplacer et renommer les fichiers et les répertoires...Ces opérations sont toutesaccessibles par le menuFichier et le menu contextuel que l’on obtient par un clic droitde la souris sur l’élément auquel l’opération doit être appliquée. Par exemple, pourchanger le nom d’un fichier, il faut 1) placer la souris sur l’icône du fichier ; 2) faireapparaître le menu contextuel par un clic droit ; 3) sélectionner l’itemRenommerdansle menu déroulant ; 4) saisir le nouveau nom.

Unix. Il existe des navigateurs similaires pour Unix, mais la manipulation des fi-chiers et des répertoires se fait normalement dans un terminal (voir section 2.3) enutilisant les commandes du système.

2.2.2. Types de fichiers

Il existe essentiellement deux types de fichiers : les fichiers de programmes, et lesfichiers de données. Parmi les fichiers de programmes, on peutdistinguer les exé-cutables au format binaire et les scripts au format texte. Les premiers sont directe-ment exécutés par le système d’exploitation. Ils ont habituellement l’extension4 .exe

commePPL.exe. Les programmes en format texte sont destinés à être interprétés.

4. Les noms de fichiers sous Windows portent normalement une extension conventionnelle,c’est-à-dire une terminaison comme.doc ou .txt . Ces extensions sont utilisées par le sys-tème d’exploitation pour leur associer une icône et pour sélectionner les programmes qui per-mettent de les visualiser, les imprimer, les éditer, etc.

Page 80: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

88 Perl pour les linguistes

C’est le cas notamment des programmes Perl dont l’extensionest .pl , comme le fi-chierbonjour.plqui se trouve dans le sous-répertoire02.Systemedu répertoirePPL5.

Les fichiers de données aussi existent sous deux formes : les données peuvent êtrecodées dans un format qui n’est lisible que par des applications particulières, commeles tablesExcel (Verbaction.xls), les archives compressées (tordre1.zip) ou les docu-mentsMicrosoft Word (LISEZMOI.doc). Les fichiers de données peuvent égalementêtre au format texte brut commeLISEZMOI.txt. Leur extension habituelle est alors.txt . Ces fichiers peuvent être créés en utilisant un éditeur de texte, générés par unprogramme ou obtenus par conversion à partir de documents préexistants.

Pour des raisons d’ergonomie, l’interface de l’Explorateur Windowsn’affiche pas,par défaut, les extensions des fichiers. Il indique par exemple que le répertoirePPLcontient un fichierLISEZMOI alors que ce dernier s’appelle en réalitéLISEZMOI.txt.

Ce comportement peut être modifié afin que les noms des fichierssoient affichésen entier. Les opérations à réaliser sont les suivantes :

1) ouvrir une fenêtreExplorateur Windows;

2) afficher la fenêtreOptions des dossiersen utilisant le menuOutils>Options desdossiers...;

3) cliquer sur l’ongletAffichage;

4) décocher la caseMasquer les extensions des fichiers dont le type est connu;

5) cliquer sur le boutonAppliquer à tous les dossiers;

6) cliquer sur le boutonOK.

Le nom du fichierLISEZMOI.txt n’est alors plus tronqué.

Unix. Les quatre types de fichiers présentés ci-dessus existent aussi sous Unix. Ladistinction entre fichier exécutable et non exécutable y estégalement effective. Chaquefichier et répertoire est en effet muni de droits d’accès qui spécifient quelles sont lesclasses d’utilisateurs autorisés à le manipuler et à l’exécuter. Ces droits peuvent êtreaffichés par la commandels -l. Les extensions des fichiers sont toujours visibles sousUnix, mais elles n’ont pas de signification particulière pour le système, et aucuneapplication n’est associée conventionnellement à un type de fichier donné.

5. Plus généralement, à l’exception dePPL.exe, tous les fichiers utilisés comme exemples dansce chapitre se trouvent dans le sous-répertoire02.Systemedu répertoirePPL, et cela sous Win-dows comme sous Unix.

Page 81: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Environnement de travail et notions de système 89

2.3. Le système d’exploitation « en direct »

L’ Explorateur Windowspermet de lancer des programmes en double-cliquant surl’icône qui leur est associée. L’installateurPPL.exea par exemple été exécuté decette manière. Ce type de lancement convient pour les programmes qui disposentd’interfaces graphiques. Ceux qui n’en ont pas doivent êtreexécutés dans un termi-nal6, c’est-à-dire en utilisant un interpréteur de commandes, également appeléshell.

2.3.1. Terminal

L’environnement de travail initial (voir paragraphe 2.1.1) inclut, sous Windows, unterminal préconfiguré (PPLterm) permettant de lancer les programmes qui n’ont pasd’interface graphique.PPLtermest disponible sur leBureauet dans le répertoirePPL.Aucun des programmes Perl présentés dans cet ouvrage ne disposant d’une interfacegraphique, tous doivent être exécutés à partir de ce terminal.

L’interpréteur de commande, leshell, est un programme qui répète la séquence detrois opérations suivante :

1) il affiche uneinvite, ouprompt, qui indique à l’utilisateur qu’il est prêt à exécu-ter une nouvelle commande ;

2) il lit une ligne de commande composée d’un nom de programmeet de ses éven-tuels options et arguments. La ligne est effectivement lue lorsque l’utilisateur tape surla touche<Entrée> ;

3) il lance le programme et lui fournit ses éventuels optionset arguments (voirparagraphe 2.3.2).

Cette séquence est réitérée jusqu’à ce que l’utilisateur soumette la commandeexit ouque le terminal soit fermé.

Par exemple, l’exécution de la ligne de commande suivante constitue une itérationde cette séquence d’opérations :

1) 2) 3)C:\PPL> C:\PPL> echo bonjour C:\PPL> echo bonjour

bonjour

C:\PPL>

La ligne de commande invoque le programmeecho avec comme argument lachaîne de caractèresbonjour . Elle affiche dans le terminal le texte qui est indiqué

6. Un lancementvia l’ Explorateur Windowsreste cependant possible pour les programmes dé-pourvus d’interface graphique à condition qu’il n’y ait ni option ni arguments à leur fournir.

Page 82: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

90 Perl pour les linguistes

à sa suite dans la ligne de commande (c’est ce texte qui constitue l’argument de lacommande). Un caractère espace doit être inséré entre le nomdu programme,echo, etl’argumentbonjour . Le prompt affiché sur la troisième ligne fait partie de l’itérationsuivante.

Unix. Aucune configuration particulière n’est nécessaire pour les utilisateurs desystèmes Unix. Le terminalxterm inclus dans l’environnement graphiqueX Windowou tout autre type de terminal permet d’exécuter correctement toutes les commandesprésentées dans cet ouvrage. Par ailleurs, tous les interpréteursshell (bash, ksh, csh,zsh, etc.) fonctionnent de la manière présentée ci-dessus.

2.3.2. Ligne de commande

Les lignes de commande sont les requêtes que l’utilisateur soumet au systèmed’exploitation pour que ce dernier les exécute. Ces lignes sont composées de troisgroupes d’éléments :

1) le nom d’un programme exécutable comme l’interpréteurperl. Ce premier élé-ment est obligatoire ;

2) un ensemble d’options qui modifient le comportement par défaut du pro-gramme. Chaque option est identifiée par un nom précédé d’un ou de deux tirets (parexemple-i ou --help ). Les options peuvent être suivies de valeurs (par exemple-n 100 ). L’ordre dans lequel les options sont listées n’a normalement pas d’impor-tance. Les options sont spécifiques à chaque programme;

3) un ensemble d’arguments qui indiquent généralement quels sont les fichiersou les données à utiliser. Les arguments d’un programme ne sont pas introduits pardes étiquettes comme c’est le cas des options. Leur interprétation est déterminée parleur position dans la liste des arguments. L’ordre des arguments doit être strictementrespecté.

Un programme peut être appelé sans options ni arguments comme la commandeexit qui permet d’arrêter leshell. La ligne de commandeecho bonjour utilisée ci-dessus comporte un argument,bonjour , mais pas d’option. La ligne de commandesuivante contient pour sa part une option et un argument :

C:\PPL> wc -w LISEZMOI.txt

393 LISEZMOI.txt

C:\PPL>

Elle permet de compter le nombre de mot contenus dans le fichier LISEZMOI.txt.Cette ligne de commande se compose 1) du nom de la commandewc ; 2) de l’option-w qui indique que l’on ne s’intéresse qu’aux mots ; 3) de l’argumentLISEZMOI.txt

Page 83: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Environnement de travail et notions de système 91

qui est le nom du fichier dont on veut compter les unités. Le résultat est affiché dansle terminal :LISEZMOI.txt contient 393 mots.

Les lignes de commande peuvent aussi comporter des élémentssupplémentairescomme des redirections (voir paragraphe 2.6.2) ou despipes(voir paragraphe 2.6.3).Les éléments qui composent les lignes de commande sont séparés les uns des autrespar des espaces. Si la valeur d’un paramètre ou d’un argumentcontient un espace, elledoit être entourée de guillemets (" ). Les guillemets sont également nécessaires pourles éléments qui contiennent des caractères qui ont un sens particulier pour une lignede commande, à savoir :

^ | & " < >

Si l’on souhaite qu’un argument de la ligne de commande contienne un de cescaractères, il est nécessaire de placer l’argument entre des guillemets. Pour le caractèrecorrespondant aux guillemets (" ), il est nécessaire de le faire précéder d’une barreoblique arrière (\ ).

Unix. La syntaxe des lignes de commande est globalement identiquesous Unix àcelle qui est présentée ci-dessus. La liste des caractères spéciaux est toutefois plusétendue, et comprend, en plus de l’espace, les caractères ci-dessous :

\ ’ " ‘ < > | ; ( ) [ ] ? # $ ^ & *

2.4. Chemins

Les chemins servent à désigner les fichiers et les répertoires qui peuvent être uti-lisés dans les lignes de commande. Il en existe essentiellement de deux types : leschemins relatifs et les chemins absolus.

2.4.1. Chemin absolu

Dans une application Windows disposant d’une interface graphique, on désignehabituellement les fichiers en naviguant à la souris dans lesdossiers de l’ordinateur.Par exemple, dansMS Word, Excel ouAdobe Reader, on ouvre un fichier par le menuFichier>Ouvrir... qui permet de parcourir les dossiers de la même manière que dansl’ Explorateur Windows.

Les programmes qui s’exécutent dans un terminal commePPLtermutilisent unautre système de désignation des fichiers. Chaque fichier et chaque répertoire y dis-pose d’un identifiant unique qui décrit sa position dans la structure hiérarchique arbo-rescente des répertoires et des fichiers. Cet identifiant représente le chemin qui relie laracine du volume au fichier ou au répertoire. Il est appeléchemin absolu. Par exemple,

Page 84: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

92 Perl pour les linguistes

le chemin du fichierLISEZMOI.txt estC:\PPL\LISEZMOI.txt. Ce chemin comporte3 éléments : la racineC:\, le dossierPPL et le fichier lui-mêmeLISEZMOI.txt. Lesdeux derniers éléments sont séparés par une barre oblique arrière ‘\’.

Appelonsrépertoire parentdex le répertoire qui contient un fichier ou un réper-toire x. Par exemple, le répertoire parent du fichierLISEZMOI.txt estPPL et celuide PPL est la racineC:\. Le chemin absolu dex est obtenu en concaténant la suitedes répertoires parents successifs dex, complétée parx lui-même. A l’exception dela racine, les noms des répertoires parents sont suivis du caractère ‘\’. Dans le cas dufichier LISEZMOI.txt, il faut donc concaténerC:\ , PPL\ et LISEZMOI.txt , ce quidonne bienC:\PPL\LISEZMOI.txt .

Si le nom de l’un des éléments qui composent le chemin contient des es-paces ou un autre caractère spécial, l’ensemble du nom doit être entouré de guille-mets (voir paragraphe 2.3.2). Par exemple, le chemin du répertoire Mes docu-ments qui se trouve sous la racineC:\ doit être écrit "C:\Mes documents" .De même le chemin du fichierListe de noms de poissons.txtqui setrouve dans le répertoireC:\PPL\02.Systemedoit être entouré de guillemets"C:\PPL\02.Systeme\Liste de noms de poissons.txt" . La ligne de com-mande suivante permet par exemple de compter le nombre de mots de ce fichier :

C:\PPL> wc -w "C:\PPL\02.Systeme\Liste de noms de poissons.txt"

2 C:\PPL\02.Systeme\Liste de noms de poissons.txt

C:\PPL>

La ligne renvoyée par la commande système indique que le fichier contient 2 mots(le nombre 2 apparaît devant le nom du fichier).

Unix. La notion de chemin absolu sous Unix est identique à celle quiest utiliséesous Windows. Les notations diffèrent cependant légèrement : 1) il n’y a sous Unixqu’une seule racine, notée par une barre oblique ‘/’ ; 2) les noms des répertoires parentssont suivis d’une barre oblique avant (‘/’) et non une barre oblique arrière (‘\’). Parexemple, lorsque l’archivePPL est installée comme cela est indiqué au paragraphe2.1.2, le chemin absolu du répertoire02.Systemeest/home/ident/PPL/02.Systemeoùidentest l’identificateur de l’utilisateur (c’est-à-dire le nomutilisé pour lelogin).

2.4.2. Répertoire de travail

L’utilisation des chemins absolus est relativement verbeuse car elle impose derépéter une grande partie de ces derniers. Par exemple, pourconcaténer les contenusdes fichiersliste-oiseaux.txtet liste-poissons.txtqui se trouvent tous les deuxdans le répertoireC:\PPL\02.Systemeet créer au même endroit un fichier résultat

Page 85: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Environnement de travail et notions de système 93

liste-animaux.txt, on peut exécuter la commandecat7 en tapant la ligne de commandesuivante :

C:\PPL> cat C:\PPL\02.Systeme\liste-oiseaux.txt

C:\PPL\02.Systeme\liste-poissons.txt >

C:\PPL\02.Systeme\liste-animaux.txt

C:\PPL>

L’ensemble de la commande doit être tapé sur une seule ligne ;il y un seul retourà la ligne, à la fin de la commande. La syntaxe des lignes de commande est détailléeen paragraphe 2.3.2.

Pour exécuter l’opération précédente, le chemin du répertoire C:\PPL\02.Systemeest répété trois fois. Afin de réduire cette redondance, les systèmes d’exploitationoffrent la possibilité de sélectionner unrépertoire de travail, également appelérépertoire courant, et de repérer les fichiers et les répertoires relativement àcedernier. Si par exemple le répertoire de travail étaitC:\PPL\02.Systeme, la ligne decommande précédente pourrait être écrite simplement :

C:\PPL\02.Systeme> cat liste-oiseaux.txt liste-poissons.txt

> liste-animaux.txt

C:\PPL\02.Systeme>

Il n’y a là aussi qu’un seul retour à la ligne à la fin de la commande. Cette lignede commande produit le même résultat que la précédente. Ellen’en diffère que parle fait qu’elle est exécutée depuis le répertoire de travailC:\PPL\02.Systemeau lieudeC:\PPL et par le remplacement des chemins absolus par des chemins relatifs. Cesdifférences apparaissent au niveau des prompts qui, par défaut, indiquent le cheminabsolu du répertoire de travail et par l’omission dans les chemins des fichiers du nomdu répertoire de travail. Le changement du répertoire de travail est présenté au para-graphe 2.4.4.

7. La commandecat concatène les fichiers qui lui sont fournis en argument. Ainsi, si liste-oiseaux.txtcontient les lignes :moineaupigeonet si liste-poissons.txtcontient les lignes :sardinetruitealors le contenu deliste-animaux.txtsera :moineaupigeonsardinetruite

Page 86: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

94 Perl pour les linguistes

Le répertoire de travail est une valeur associée aushell. Lorsque plusieursshells’exécutent en même temps dans des fenêtres différentes, chacun dispose de sonpropre répertoire de travail.

2.4.3. Chemin relatif

Les chemins relatifs sont similaires aux chemins absolus. Ils permettent d’identi-fier les fichiers et les répertoires relativement à une origine variable (le répertoire detravail), et non par rapport à une origine absolue (la racinedu volume). Le principede l’adressage reste le même, c’est-à-dire que l’on décrit la position d’un fichier oud’un répertoirex par le chemin qui relie le répertoire de travail àx. Par exemple, si lerépertoire de travail courant estC:\PPL, le chemin relatif du fichierliste-animaux.txtutilisé ci-dessus est02.Systeme\liste-animaux.txt.

Les chemins relatifs permettent naturellement de localiser aussi des fichiers oudes répertoires qui ne sont pas contenus dans le répertoire de travail. Ces cheminsutilisent la notation particulière ‘.. ’ pour représenter le répertoire parent immédiatdu répertoire précédent (ou du répertoire de travail courant s’ils figurent en début dechemin).

Par exemple, si le répertoire de travail estC:\PPL\02.Systeme, le chemin rela-tif du fichier C:\PPL\LISEZMOI.txt utilisé en section 2.2 serait..\LISEZMOI.txt.Dans cette expression,.. désigne le répertoire parent du répertoire de travail (doncC:\PPL). De même, le chemin relatif..\.. désigne la racine (C:\). Les premiers..représentent le parent immédiat du répertoire de travail (donc C:\PPL) et les seconds,le répertoire parent du précédent (c’est-à-direC:\).

2.4.4. Changement de répertoire de travail (cd)

Le principal intérêt de la notion de répertoire de travail est que ce dernier peut êtremodifié selon les besoins de l’utilisateur. Le changement derépertoire de travail se faiten utilisant le commandecd8 qui prend comme argument le chemin du répertoire quel’on choisit comme nouveau répertoire de travail ; ce dernier peut être relatif ou absolu.Par exemple, lorsqu’on lance un terminal par l’intermédiaire du raccourciPPLtermqui se trouve sur leBureau, le répertoire de travail initial estC:\PPL. Pour travaillersur des fichiers qui se trouvent dans le sous-répertoire02.Systeme, on exécutera doncla commande :

C:\PPL> cd 02.Systeme

C:\PPL\02.Systeme>

8. cd signifiechange directory.

Page 87: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Environnement de travail et notions de système 95

On peut vérifier le succès de la commande en considérant le prompt affiché aprèsson exécution. Si par la suite on doit travailler sur des données qui se trouvent dans lerépertoireC:\PPL\Corpus, on pourra par exemple exécuter la commande :

C:\PPL\02.Systeme> cd C:\PPL\Corpus

C:\PPL\Corpus>

Le répertoire destination peut aussi être désigné par un chemin relatif :

C:\PPL\02.Systeme> cd ..\Corpus

C:\PPL\Corpus>

2.5. Lancement des programmes Perl

Langage de programmation interprété. Les programmes écrits en Perl sont exé-cutés par un interpréteur et non directement par le système d’exploitation comme lesexécutables. L’interpréteur, que l’on invoque par la commandeperl, lit le texte d’unprogramme et effectue les opérations qui y sont décrites.

Ligne de commande. Pour exécuter un programme Perl, on doit lancer l’inter-préteur en lui indiquant le fichier qui contient le programme. La ligne de commandecomporte ainsi deux parties : la commandeperl qui lance l’interpréteur avec ses éven-tuelles options ; l’argument de cette commande, à savoir le programme Perl, qui peutlui aussi avoir des options et des arguments. Le programme Perl doit toujours être lepremier argument de la commandeperl.

Par exemple, la ligne de commande suivante permet d’exécuter le programme Perlbonjour.pl9 qui affiche le messagebonjour à tous !:

C:\PPL\02.Systeme> perl bonjour.pl

bonjour à tous !

C:\PPL\02.Systeme>

L’interpréteurperl est invoqué avec comme argument le programmebonjour.pl. perlpeut aussi être appelé avec des options comme dans l’exemplesuivant :

C:\PPL\02.Systeme> perl -w pluriels.pl liste-animaux.txt

moineaux

pigeons

sardines

truites

C:\PPL\02.Systeme>

9. Le programmebonjour.plse trouve dans le répertoireC:\PPL\02.Systeme.

Page 88: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

96 Perl pour les linguistes

où le programmepluriels.pl est exécuté pour calculer les formes au pluriel des nomsqui se trouvent dans le fichierliste-animaux.txt10(voir chapitre 3 pour une présenta-tion détaillée de différents programmes de flexion nominale). La ligne de commandeprécédente invoqueperl avec une option-w pour lui demander d’afficher des avertis-sements si le programme qu’il doit exécuter contient des constructions douteuses11.L’interpréteurperl a comme premier argument le programmepluriels.pl. Les élémentsqui suivent sont les options et les paramètres du programme Perl. Le nom de fichierliste-animaux.txtest donc le premier argument depluriels.pl et lui sera donc transmispar l’interpréteur.

Plus généralement, la ligne de commande qui lance un programme Perl peut com-porter les éléments suivants :

1) le nom de l’interpréteur (perl ) ;

2) les éventuelles options de l’interpréteurperl comme-w . Signalons égalementl’option -c qui permet de vérifier que le programme est syntaxiquement correct sansl’exécuter ;

3) le chemin du programme Perl qui doit obligatoirement êtrele premier argumentde l’interpréteur ;

4) les éventuelles options du programme Perl. Ces options sont décidées par leprogrammeur ;

5) les éventuels arguments du programme Perl, eux aussi décidés par le program-meur.

L’ordre de ces éléments est important. En particulier, il nefaut pas confondre lesoptions de l’interpréteur qui se placent immédiatement après la commandeperl aveccelles du programme qui se trouvent juste après le nom du programme.

Par exemple, on peut indiquer au programmepluriels.plqu’il doit afficher à la foisles formes au singulier et au pluriel des mots du fichier en utilisant l’option-s :

C:\PPL\02.Systeme> perl -w pluriels.pl -s liste-animaux.txt

10. pluriels.plet liste-animaux.txtse trouvent dans le répertoireC:\PPL\02.Systeme. Rappelonsqueliste-animaux.txtcontient :moineaupigeonsardinetruite

11. L’absence d’avertissement ne signifie pas que le programmePerl est correct, mais seulementqu’il respecte un certain nombre de règles simples de « bonneprogrammation ».

Page 89: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Environnement de travail et notions de système 97

moineau moineaux

pigeon pigeons

sardine sardines

truite truitesC:\PPL\02.Systeme>

(Voir chapitre 7 pour d’autres exemples de programmes disposant d’options.)

Arrêt d’un programme Perl. On peut arrêter l’exécution d’un programme Perlavant sa fin normale en tapant Ctrl-C (^C) dans le terminal, notamment lorsque l’onconstate qu’il ne se comporte pas comme prévu.

2.6. Entrées/sorties

Les programmes exécutés dans un terminal opèrent sur des entrées qui leur sonttapées au clavier et écrivent leurs résultats dans le terminal (à l’écran). C’est le casdu programmepluriels2.plqui est identique àpluriels.pl excepté que les mots dont ilcalcule les pluriels sont entrés au clavier et non lus dans unfichier :

C:\PPL\02.Systeme> perl -w pluriels2.pl

âne<Entrée>

ânes

cheval<Entrée>

chevaux

pou<Entrée>

poux

punaise<Entrée>

punaises

^Z<Entrée>

C:\PPL\02.Systeme>

Rappelons que le texte en gras est celui qui est tapé par l’utilisateur et que le texteen maigre correspond à ce qui est affiché dans le terminal. La frappe sur la touche<Entrée> à la fin de la ligne de commande n’a pas été explicitée. Le programmepluriels2.pl affiche à l’écran le pluriel de chaque mot qui lui est fourni. La lecturepuis le traitement du mot par le programme se font au moment oùl’utilisateur frappela touche<Entrée> . Le fait que les entrées et les sorties soient entremêlées sur leterminal est simplement dû au fait que les mots tapés par l’utilisateur sont affichésdans le même écran que les résultats du programme. On indiqueau programme qu’iln’y a plus de nouveau nom à fléchir en tapant Ctrl-Z (^Z ) suivi d’un retour à la ligne.

Unix. Sous Unix, il faut taper Ctrl-D (D) sans retour à la ligne pour indiquer qu’iln’y a plus d’entrée à traiter.

Page 90: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

98 Perl pour les linguistes

2.6.1. Flux

Un programme qui s’exécute dans un terminal voit les caractères tapés au claviercomme provenant d’unflux d’entrée standard, notéSTDIN. Le flux d’entrée standardest la source de données par défaut de tous les programmes. Dans l’exemple précé-dent, le flux d’entrée standard contient l’ensemble du texteen gras, à l’exception dela dernière ligne. Cette ligne contient en effet le caractère de fin de fichier Ctrl-Z (Z )qui indique ici àpluriels2.plqu’il n’y a plus d’autres noms à traiter. Pour être pris encompte, ce caractère doit être suivi d’un retour à la ligne. (Sous Unix, le caractère defin de fichier est Ctrl-D (D), sans retour à la ligne.)

De façon similaire, les caractères affichés à l’écran sont enfait écrits par les pro-grammes dans unflux de sortie standard, notéSTDOUT. C’est la destination par défautdes résultats de tous les programmes. Dans l’exemple précédent, le flux de sortie stan-dard contient le texte en maigre compris entre la ligne de commande et le promptfinal.

Le terminal dispose aussi d’un troisième flux standard, leflux d’erreur standard,noté STDERR, sur lequel s’affichent les avertissements et les messages d’erreurscomme :

C:\PPL\02.Systeme> perl -w pluriels.pl

Usage : pluriels.pl [-s] FICHIER

C:\PPL\02.Systeme>

qui indique à l’utilisateur quepluriels.pl attend un argument obligatoire, le fichier denoms, et qu’il accepte une option-s. Ce message a été produit par le programme car laligne de commande ne correspond pas à ce qui était attendu. Lecontenu deSTDERRest aussi affiché dans le terminal, c’est-à-dire à l’écran.

2.6.2. Redirections

Il n’est pas toujours possible ou souhaitable de saisir les entrées d’un programmeau clavier ou d’utiliser des résultats affichés à l’écran, notamment lorsque les donnéesà traiter sont volumineuses. Pour résoudre ce problème, leshell permet de remplacerles flux standards par des fichiers texte. Il est par exemple possible d’indiquer au ni-veau de la ligne de commande que les entrées du programmepluriels2.pl ne serontpas saisies au clavier mais qu’elles se trouvent dans le fichier liste-animaux.txt. Onutilise pour cela l’opérateur de redirection du flux d’entrée standard ‘<’ :

C:\PPL\02.Systeme> perl -w pluriels2.pl < liste-animaux.txt

moineaux

pigeons

sardines

Page 91: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Environnement de travail et notions de système 99

truites

C:\PPL\02.Systeme>

Cette redirection permet d’utiliser les programmespluriels2.pl et pluriels.pl de ma-nière identique.

Le flux de sortie standard peut lui aussi être redirigé pour conserver dans un fichierles résultats qui s’affichent normalement à l’écran. On utilise pour cela l’opérateur‘>’. Par exemple, pour que les résultats de l’exécution de laligne de commandeprécédente soient stockés dans un fichierliste-animaux-pluriels.txt, il suffit de lacompléter comme suit :

C:\PPL\02.Systeme> perl -w pluriels2.pl < liste-animaux.txt

> liste-animaux-pluriels.txt

C:\PPL\02.Systeme>

La commande n’affiche alors plus rien à l’écran. Si avant le lancement de lacommande, un fichierliste-animaux-pluriels.txtexiste dans le répertoire de travailC:\PPL\02.Systeme, son contenu initial est remplacé par les résultats de la commande.Dans le cas contraire, un nouveau fichierliste-animaux-pluriels.txtest créé. Une foiscette commande exécutée,liste-animaux-pluriels.txtcontient :

moineaux

pigeons

sardines

truites

Il est naturellement possible de rediriger la sortie standard uniquement et de taper auclavier les éventuelles entrées du programme.

Le shell dispose d’un deuxième opérateur de redirection du flux de sortiestandard, ‘>>’ qui permet d’écrire les sorties d’une commande à la fin d’un fichierexistant en préservant son contenu initial. Par exemple, s’il n’existe pas de fichierliste-animaux-pluriels2.txtdans le répertoireC:\PPL\02.Systemeet si l’on exécutesuccessivement les commandes suivantes12:

C:\PPL\02.Systeme> perl -w pluriels2.pl -s <

liste-oiseaux.txt >> liste-animaux-pluriels2.txt

C:\PPL\02.Systeme> perl -w pluriels2.pl < liste-poissons.txt

>> liste-animaux-pluriels2.txt

C:\PPL\02.Systeme>

12. Notez quepluriels2.plest appelé avec l’option-s dans la première ligne de commande.

Page 92: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

100 Perl pour les linguistes

Le fichier liste-animaux-pluriels2.txtest créé par cette commande et contient leslignes de texte suivantes :

moineau moineaux

pigeon pigeons

sardines

truites

Les directives de redirection doivent toujours se trouver àla fin de la ligne de com-mande. Ces directives sont traitées directement par leshell : ni l’interpréteurperl ni leprogrammepluriels2.pln’en ont connaissance. De leur point de vue, seuls existent lesflux standards. Ainsi, si le fichier sur lequel l’entrée standard est redirigée n’existe pas,notamment si l’utilisateur se trompe dans son nom, c’est le système d’exploitation quiaffiche un message d’erreur :

C:\PPL\02.Systeme> perl -w pluriels2.pl < liste-animal.txt

Le fichier spécifié est introuvable.

C:\PPL\02.Systeme>

2.6.3. Tube (pipe)

Il arrive souvent que pour réaliser une opération complexe,on doive enchaîner unesérie d’opérations plus élémentaires.

Par exemple, pour calculer les pluriels des noms d’animaux qui se trouvent dansles fichiersliste-oiseaux.txtet liste-poissons.txt, et sauvegarder le résultat dansliste-animaux-pluriels3.txt, on doit réaliser deux opérations :

1) concaténer les fichiersliste-oiseaux.txtet liste-poissons.txten un fichiertem-poraire.txt;

2) calculer les formes plurielles des noms detemporaire1.txtet conserver les ré-sultats dans un fichierliste-animaux-pluriels3.txt.

Ces opérations sont réalisées respectivement les deux lignes de commande suivantes :

C:\PPL\02.Systeme> cat liste-oiseaux.txt liste-poissons.txt

> temporaire.txt

C:\PPL\02.Systeme> perl pluriels2.pl -s < temporaire1.txt >

liste-animaux-pluriels3.txt

C:\PPL\02.Systeme>

Une fois ces commandes exécutées, on dispose d’un fichierliste-animaux-pluriels3.txtqui contient :

moineau moineaux

pigeon pigeons

sardine sardines

truite truites

Page 93: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Environnement de travail et notions de système 101

Mais cette séquence de commandes a aussi créé un fichier intermédiaire (tempo-raire.txt) qui n’est pas utile à l’utilisateur. Pour éviter d’avoir à multiplier ce typede fichier intermédiaire, leshell fournit un opérateurtube (habituellement désignépar le terme anglais originalpipe), noté ‘|’, qui redirige la sortie standard d’unecommande sur l’entrée standard de la suivante. Ainsi, la ligne de commande suivantepermet de créerliste-animaux-pluriels3.txtdirectement à partir deliste-oiseaux.txtetliste-poissons.txtsans fichier temporaire :

C:\PPL\02.Systeme> cat liste-oiseaux.txt liste-poissons.txt

| perl pluriels2.pl -s > liste-animaux-pluriels3.txt

C:\PPL\02.Systeme>

L’utilisation despipesprésente en outre d’autres avantages, notamment :

1) toutes les opérations sont réalisées en mémoire. Le tempsd’exécution se trouveainsi réduit puisqu’on évite l’écriture sur le disque des fichiers temporaires puis leurrelecture. La contrepartie est un besoin accru en espace mémoire ;

2) les commandes sont exécutées et démarrent toutes en même temps.

2.6.4. Affichage paginé (more)

Plusieurs commandes permettent d’afficher à l’écran le contenu d’un fichier, no-tammentcat et type. Cependant ces deux commandes ne sont pas adaptées à la lecturedes fichiers à l’écran par l’utilisateur car elles affichent la totalité du fichier d’un coup,sans tenir compte de la taille du terminal.

Pour lire un fichier à l’écran, il est préférable d’utiliser une commande d’affichagepaginé commemore. Cette commande affiche le contenu du fichier page par pagepour en permettre la lecture humaine. Chacune des pages a la taille du terminal. Parexemple, pour lire à l’écran le fichiertordre1.txtqui provient du corpus ABU, on peutlancer la commande suivante :

C:\PPL\02.Systeme> more tordre1.txt

moreprend alors possession du terminal et remplace le texte initialement affiché surl’écran par la première page du texte. La dernière ligne du terminal présente un ban-deau indiquant notamment la position de la page dans le texte(sous la forme d’unpourcentage). On doit ensuite taper<Espace> ou <Entrée> pour afficher la pagesuivante et ‘q’ pour quitter l’application et revenir aushell. L’écran initial est alorsrétabli.

La commandemore est souvent utilisée pour lire à l’écran les résultats destraitements comme dans l’exemple suivant (voir programme 5.6 au paragraphe5.3.2.1, page 205) :

Page 94: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

102 Perl pour les linguistes

C:\PPL\02.Systeme> perl adjectifs-able.pl < tordre1.tag |

more

On peut ainsi prendre connaissance rapidement des résultats de la commande. Onévite ainsi la sauvegarde des 82 adjectifs extraits dans un fichier puis l’ouverture dece dernier dans un éditeur de texte commeSciTE pour les visualiser (voir paragraphe2.7.2).

2.7. Complément de l’environnement de travail

Cette section est consacrée à l’installation de l’outil de compression et décom-pression7-Zip, de l’éditeurScite, du catégoriseurTreeTagger, du lexique morpho-syntaxiqueMorphalouet des modules Perl utilisés par les programmes de traitementdes documents XML et de manipulation des pages Web. Elle présente également lesystème d’aide en ligneperldocet les adaptations à réaliser dans les environnementsUnix dont le codage des caractères principal est Unicode (UTF-8).

2.7.1. 7-Zip (Windows)

L’un des premiers outils qu’il faut installer sous Windows est un décompresseurd’archives (voir paragraphe 1.4.3). Plusieurs utilitaires sont disponibles dont certainscommeWinzip ou Power Archiversont payants, et d’autres gratuits, notamment7-Zip. Nous conseillons d’installer et d’utiliser ce dernier logiciel qui permet aussi demanipuler les archives au formattar.

7-Zip peut être téléchargé sur le site de ce logiciel :http://www.7-zip.org/fr/

en cliquant sur le lienTéléchargerde type.msicorrespondant à l’architecture de l’or-dinateur (32-bitsoux64) sur lequel7-Zip doit être installé. On doit ensuite choisir l’undes sites qui proposent le logiciel et cliquer sur le lienDownload. Une icône portant lenom7zipsuivi d’un numéro de version apparaît alors sur le bureau (voir note 1, page84). L’installation proprement dite se fait ensuite de la manière suivante :

1) double-cliquer sur l’icône de l’installateur7-Zip ;

2) cliquer sur le boutonNext;

3) accepter la licence d’utilisation en cochant la caseI accept the terms of theLicence Agreementpuis cliquer surNext;

4) cliquer sur le boutonNextsans modifier les paramètres par défaut ;

5) cliquer sur le boutonInstall ;

6) cliquer sur le boutonFinish.

Page 95: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Environnement de travail et notions de système 103

On peut alors utiliser7-Zip en l’invoquant à partir du menuDémarrer>Tous lesprogrammes>7-Zip>7-ZIP File Managerou bienvia les menus contextuels en cli-quant avec le bouton droit sur les archives à décompresser (ou les fichiers à ajouter àune archive) puis en sélectionnant l’item7-Zippuis l’une des opérations proposées :

– Open archivepour explorer l’archive sans la décompresser ;

– Extract Files...pour décompresser l’archive dans un répertoire particulier ;

– Extract Herepour décompresser l’archive dans le répertoire où elle se trouve ;

– Add to archive...pour ajouter un fichier à une nouvelle archive ou à une archiveexistante.

Unix. L’outil de compression et de décompressiongzip est fourni, de base, partous les systèmes Unix. La décompression des archivesZIP nécessite un utilitairespécifique,unzip (voir paragraphe 1.4.3).

2.7.2. Editeur de texteSciTE

Si l’interpréteurperl est indispensable pour exécuter des programmes Perl, il n’estconçu ni pour les créer ni pour les modifier. Il faut pour cela utiliser d’autres outils,mieux adaptés, comme les éditeurs de texte.

Windows inclut lui aussi un éditeur de texte de base : leBloc-notes. Mais cet édi-teur est très rudimentaire et ne dispose d’aucune fonctionnalité permettant d’écrirefacilement et de visualiser correctement des programmes Perl. C’est également le casdes traitements de texte commeMicrosoft WordouOpenOfficequi autorisent l’enre-gistrement des documents en texte brut.

Pour éditer des textes, que ces derniers soient des programmes Perl, des corpus oudes lexiques, il est important d’utiliser un bon éditeur de texte car c’est l’outil que l’onpasse le plus de temps à utiliser lorsque l’on écrit et met au point des programmes.Parmi les différents éditeurs adaptés à la programmation enPerl et à la manipulationdes données textuelles et lexicales, nous recommandonsSciTE13 qui dispose d’uneinterface relativement intuitive. L’environnement de travail initial inclut cet éditeur detexte. Il peut être lancé à partir des raccourcis qui se trouvent sur leBureauet dansC:\PPL ou bien directement depuis le répertoire dans lequel il est installéC:\SciTE.Avant d’écrire un nouveau programme, il faut sélectionner le langage de programma-tion Perl dans le menuLangagepour que la gestion de l’indentation et l’affichage desdifférents éléments de la syntaxe Perl soient corrects.

13. http://www.scintilla.org .

Page 96: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

104 Perl pour les linguistes

Unix. L’utilisation d’éditeurs de texte est courante sous Unix. L’éditeurvi fait parexemple partie, de base, des systèmes Unix. L’éditeurSciTE est également disponiblepour les systèmes Unix, et peut être téléchargé librement sur son site.

2.7.3. Installation des modules supplémentaires

Les distributions de base de l’interpréteurperl n’incluent pas certains modulesutilisés dans les programmes proposés dans l’ouvrage. C’est notamment le cas desmodules de traitement des documents XML et de manipulation des pages Web.

2.7.3.1.Windows

L’ajout de modules dansActivePerl se fait en utilisant l’utilitaireppm (Perl Pa-ckage Manager) dont les versions récentes disposent d’une interface graphique.ppmpeut être lancé dans un terminal ou par l’intermédiaire du menu Démarrer>Tous lesprogrammes>ActivePerl>Perl Package Manager. ActivePerl est fourni avec un en-semble étendu de modules préinstallés.

Les modules manquants peuvent être installés en exécutant la commande suivante :

C:\PPL> PPL-installer-modules.bat

et en validant les réponses par défaut proposées parppm (c’est-à-dire en appuyant surla touche<Entrée> ).

Cette commande automatise l’installation des paquetages :

XML::DOMXML::SAXXML::Writer

ainsi que des modules qui en dépendent. Signalons que dans les noms de paquetageutilisés parppm, les ‘::’ sont remplacés par des ‘-’. Par exemple, le paquetage quicorrespond àXML::DOMs’appelleXML-DOM.

2.7.3.2.Unix

L’installation de modules ne peut être effectuée que par l’administrateur du sys-tème.

Le mode d’installation de modules le plus simple consiste à faire appel au gestion-naire de paquetages des systèmes qui en ont un (commeapt ou rpm). Il existe en effetdes collections très importantes de paquetages de bibliothèques ou modules Perl. Ilsuffit d’identifier les paquetages qui contiennent les modules que l’on souhaite utiliserpuis de les installervia le gestionnaire de paquetages.

Page 97: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Environnement de travail et notions de système 105

La deuxième méthode est la plus générale. Elle utilise l’interpréteurperl et lemoduleCPAN14 pour automatiser le téléchargement et l’installation des modules.CPAN est un module de base des interpréteursperl.

L’installateur de modules peut être lancé en mode interactif via la commande sui-vante :

ident @labo:~> perl -MCPAN -e shell

Lors de sa première utilisation, une configuration de l’utilitaire est effectuée. Ellen’exige pas de connaissances particulières du système : il suffit de valider les réponsespar défaut proposées. Une fois la configuration terminée, unprompt indique que descommandes peuvent être soumises à l’installateur. On peut ainsi connaître la liste desmodules dont le nom peut être mis en correspondance avec une expression régulière(voir chapitre 4) en utilisant la commandei / expression / comme dans l’exemplesuivant :

cpan> i /XML/

Cette commande fournit la liste des modules disponibles dont le nom contientla sous-chaîneXML. Une fois identifié le nom exact des modules que l’on souhaiteutiliser, on les installe par la commandeinstall <Nom du module> . Par exemple,pour installer le moduleXML::Writer , on soumet la commande :

cpan> install XML::Writer

La commandeexit permet de quitter l’installateur et de revenir aushell de dé-part :

cpan> exit

ident @labo:~>

La liste des modules présentés et utilisés dans les chapitres 9 et 10 est :

HTML::EntitiesLWP::SimpleSOAP::LiteURI::URLXML::DOMXML::ParserXML::SimpleXML::Writer

14. CPAN (Comprehensive Perl Archive Network) est le nom du principal dépôt de ressourcesPerl. Il propose notamment la plus importante collection demodules disponibles. Son URL est :http://www.cpan.org/ .

Page 98: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

106 Perl pour les linguistes

On peut vérifier si un module est déjà installé ou non en exécutant dans un terminalla commandeperl -e "use <Nom du module> ;" comme par exemple :

ident@labo:~> perl -e "use URI::URL;"

L’absence de message d’erreur indique que le module est déjàinstallé.

2.7.4. Aide en ligne (perldoc)

L’interpréteurperl inclut un système d’aide en ligne très complet, accessibleviala commandeperldocde la manière suivante :

perldoc perl donne la liste des sections de la documentation de Perl.

perldoc <section> affiche la documentation de la section. Par exemple, la com-mandeperldoc perlfunc fournit la documentation de toutes les fonctionsprédéfinies du langage Perl.

perldoc -f <fonction> affiche la documentation de la fonction. Par exemple,la commandeperldoc -f substr produit la documentation de la fonctionsubstr (extraction de sous-chaînes).

perldoc <Nom de module> affiche la documentation du module. Il faut respecterla casse majuscule ou minuscule des lettres du nom du module.L’option -i

permet d’ignorer la casse des arguments deperldoc (perldoc -i <nom de

module> ). Par exemple,perldoc Getopt::Std donne accès au manuel dumoduleGetopt::Std (analyse des options). Cette même documentation peutaussi être obtenue parperldoc -i Getopt::std .

perldoc -q <RegExp> affiche les entrées de la FAQ (foire aux questions) qui cor-respondent à l’expression régulière. Par exemple,perldoc -q "file" listeles entrées de la FAQ dont le titre contient la séquencefile.

La documentation de Perl est également consultablevia un navigateur Web.Sous Windows, elle peut être visualisé en utilisant le menuDémarrer>Tous les pro-grammes>ActivePerl>Documentation. La liste des sections se trouve dans le cadre degauche.

2.7.5. Adaptation des environnements Unix

Les différents systèmes de la famille Unix (et les différentes distributions de Li-nux) peuvent être configurés de façon différente en ce qui concerne le codage descaractères. Pour simplifier la présentation des programmes, nous avons choisi tout au

Page 99: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Environnement de travail et notions de système 107

long de l’ouvrage de considérer qu’ils sont exécutés avec lecodage par défaut de Perl,Latin1. De plus en plus de systèmes Unix sont toutefois configurés par défaut avecle système de codage universel Unicode (UTF-8). Les utilisateurs de ces systèmesdoivent prendre cette situation en compte, sous peine de voir certains programmesfonctionner de façon impropre lorsque les données traitéescontiennent des lettres ac-centuées.

Les annexes A2 et A3 présentent en détails les principes du codage des carac-tères et de la localisation, notamment les problèmes qui peuvent être rencontrés et lessolutions permettant de les résoudre.

Pour un utilisateur d’un système Unix, la façon la plus simple de savoir si sonenvironnement de travail est en Unicode est de taper dans la commande suivante :

ident@labo:~> locale

Dans un environnement de travail enLatin1, cette commande affiche plusieurslignes du type :

LANG=fr_FR

LC_CTYPE="fr_FR"

En revanche, si la partie droite de ces lignes se termine parUTF-8 :

LANG=fr_FR.UTF-8

LC_CTYPE="fr_FR.UTF-8"

alors cela signifie que l’environnement de travail est en Unicode, et que des adapta-tions sont à prévoir. Nous conseillons fortement aux utilisateurs dans cette situationde modifier leur environnement de travail afin d’utiliser le codageLatin1 (voir annexeA3, paragraphe A3.3.2).

Ceux qui souhaitent néanmoins faire fonctionner des programmes Perl dans cet en-vironnement sont invités à lire en détail l’annexe A2 et particulièrement le paragrapheA2.6.5.

2.7.6. TreeTagger

Le TreeTagger15est un catégoriseur et un lemmatiseur développé à l’IMS (univer-sité de Stuttgart) qui présente de nombreux avantages :

– il fonctionne de façon identique sous Windows et sous Unix (Linux et Mac-OS X) ;

15. http://www.ims.uni-stuttgart.de/projekte/corplex/Tr eeTagger/ .

Page 100: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

108 Perl pour les linguistes

– il est gratuit ;

– il est directement téléchargeable sur le site de l’IMS (pasde convention préalableà signer) ;

– des fichiers de paramètres sont disponibles pour plusieurslangues dont le fran-çais, l’ancien français, l’anglais, l’allemand, l’italien, l’espagnol, etc. ;

– ses résultats sont d’une qualité satisfaisante.

Ces caractéristiques font duTreeTaggerun outil de référence pour le traitement auto-matique des textes en français. C’est aussi le catégoriseurqui est utilisé dans la suitede l’ouvrage pour l’annotation morphosyntaxique. Le paragraphe 1.7.3 présente endétail son utilisation et les résultats qu’il produit.

Le TreeTaggerse compose essentiellement de deux parties : 1) le catégoriseur pro-prement dit ; 2) des fichiers de paramètres spécifiques à chaque langue qui contiennentun segmenteur en mots, les informations lexicales et les règles d’étiquetage. Ses com-posants doivent donc être téléchargés par l’utilisateur sur la page Web du catégoriseur :

http://www.ims.uni-stuttgart.de/projekte/corplex/Tr eeTagger/

puis décompressés dans les répertoires prévus. Il est indispensable de prendre connais-sance de la licence d’utilisation duTreeTaggeravant de l’installer :

http://www.ims.uni-stuttgart.de/~schmid/Tagger-Lice nce

2.7.6.1.Windows

Pour utiliser leTreeTaggersous Windows, il faut télécharger deux archives com-pressées :

– la première contient les fichiers de paramètres pour le français. Cette archive auformatgzip est commune aux versions Windows et Linux. Elle est téléchargée en cli-quant sur le lienFrench parameter filequi se trouve dans la sectionParameter filesfor PC (Linux and Windows)de la page Web duTreeTagger. Une fois le télécharge-ment terminé, un fichierfrench-par-linux-3.1.bin.gzapparaît sur leBureau(voir note1, page 84) ;

– la seconde archive, au format ZIP, contient la version Windows du caté-goriseur. On la télécharge en cliquant sur le lienWindows version. Un fichiertree-tagger-windows-3.1.zipapparaît alors sur leBureau(voir note 1, page 84).

Pour installer leTreeTagger, il faut :

1) ouvrir l’archivetree-tagger-windows-3.1.zipen utilisant7-Zip ;

2) extraire le répertoireTreeTaggerdansC:\ (cliquer sur le boutonExtraire, indi-querC:\ dans la fenêtreCopier, puis cliquer surOK) ;

3) quitter7-Zip ;

Page 101: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Environnement de travail et notions de système 109

4) ouvrir l’archivefrench-par-linux-3.1.bin.gzen utilisant7-Zip ;

5) extraire le fichierfrench.pardans le répertoireC:\TreeTagger\lib\(cliquer sur leboutonExtraire, indiquerC:\TreeTagger\lib\ dans la fenêtreCopier, puis cliquersurOK) ;

6) quitter7-Zip.

Le TreeTaggerdoit être lancé depuis le répertoire dans lequel se trouve letexte à catégoriser en utilisant la commandetag-french (voir paragraphe 1.7.3).Une deuxième commandetag-french-desambpermet de désambiguïser les éventuelslemmes ambigus produits par leTreeTagger.

2.7.6.2.Unix

L’installation duTreeTaggersous Unix est similaire à celle sous Windows. Elleen diffère par les répertoires d’installation et par le faitque l’utilisateur doit modifierlui-même la variablePATH:

1) créer un répertoireTreeTaggerdans le répertoire principal de l’utilisateur~/ ;

2) télécharger dans~/TreeTaggerles fichiers de paramètres correspondant au sys-tème d’exploitation de l’ordinateur sur lequel leTreeTaggerdoit être installé :

- pour les ordinateurs sous Linux, les fichiers de paramètresà utiliser setrouvent dansfrench-par-linux-3.1.bin.gzque l’on télécharge en cliquant sur le lienFrench parameter filede la sectionParameter files for PC (Linux and Windows);

- pour les ordinateurs sous Mac OS X, les fichiers de paramètres à utiliser setrouvent dansfrench-par-3.1.bin.gzque l’on télécharge en cliquant sur le lienFrenchparameter filede la sectionParameter files for Sparc-Solaris and Mac OS-X;

3) télécharger dans~/TreeTaggerla version du catégoriseur qui correspondau système de la machine : le lienPC-Linux permet de télécharger le fichiertree-tagger-linux-3.1.tar.gzetMac OS-X, le fichiertree-tagger-MacOSX-3.1.tar.gz;

4) télécharger dans~/TreeTaggerle fichier de scriptstagger-scripts.tar.gzen cli-quant sur le lientagging scripts;

5) enregistrer dans~/TreeTaggerle script d’installationinstall-tagger.shdispo-niblevia le lien install-tagger.sh.

Une fois l’ensemble des fichiers téléchargés, il faut exécuter dans un terminal lescript install-tagger.sh:

ident @labo:~/TreeTagger> sh ./install-tagger.sh

Il faut ensuite rajouter à la variablePATH les répertoires~/TreeTagger/cmdet~/TreeTagger/bin. Cette variable doit être positionnée dans les fichiers de démarragede la session. Par exemple, les utilisateurs dont leshell estbashdoivent ajouter leslignes suivantes au fichier~/.bash_profile:

Page 102: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

110 Perl pour les linguistes

export PATH=$PATH:/home/ ident /TreeTagger/cmd

export PATH=$PATH:/home/ ident /TreeTagger/bin

où /home/ ident / doit être remplacé par le chemin absolu du répertoire principal del’utilisateur,~/.

La commandetree-tagger-frenchdu sous-répertoirecmd permet de lancer leTree-Taggeravec un paramétrage par défaut (voir paragraphe 1.7.3). La commandetree-tagger-french-desambréalise en plus la désambiguïsation des lemmes ambigus.

2.7.7. Morphalou

Le lexiqueMorphalouest distribué par l’ATILF sur le site du CNRTL (voir para-graphe 1.5.2.3). La licence d’utilisation de cette ressource ne permet pas de la redis-tribuer. Elle doit donc être téléchargée et installée directement par chaque utilisateur.

Le téléchargement deMorphalouse fait depuis le site du CNRTL :http://www.cnrtl.fr/lexiques/morphalou/

Cliquer sur le boutonTélécharger Morphalou 1.0, puis accepter la licenceMor-phalouen cliquant sur le boutonAccepterqui se trouve à la fin du texte. Le téléchar-gement démarre automatiquement (enregistrer le fichier surle disque). Une fois ter-miné, un fichierMorphalou1.zipapparaît sur le bureau (voir note 1, page 84). Extrairel’archive dans le répertoireC:\PPL\Lexiques. Ce dernier contient alors deux nouveauxfichiersMorphalou-1.0.1.xmlet Morphalou-1.0.1.dtd.

Le lexiqueMorphalouest difficile à manipuler directement, à cause de sa taille etde la répartition des informations dans sa structure XML. Onpeut cependant simplifierson utilisation en créant une version dans un format tabulé classique avec un codagecompact des traits morphosyntaxiques (en l’occurrence le jeu d’étiquettes Grace16;voir paragraphe 1.5.2.8).

Cette conversion est réalisée par l’utilitairemorphalou2grace.pl. Il faut se placerdans le répertoire de travailC:\PPL\Lexiquespuis lancer la commande suivante17:

C:\PPL\Lexiques> perl morphalou2grace.pl Morphalou-1.0.1.xml

16. Morphaloune comporte pas de description complète pour les mots fonctionnels. Ces der-niers sont munis, dans la version compacte, d’une étiquetteF qui recouvre les catégoriesP, D,S etCdu jeu d’étiquettes Grace.17. Ce programme utilise le moduleXML::Parser qu’il faut installer (voir paragraphe 2.7.3)avant de réaliser la conversion.

Page 103: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Environnement de travail et notions de système 111

L’exécution de la commande peut durer quelques minutes. Unefois terminée, lerépertoireC:\PPL\Lexiquescontient un fichiermorphalou.txtqui sera notamment uti-lisé pour l’ensemble des traitements du chapitre 8.

2.8. Aborder la suite de l’ouvrage

La présentation de l’environnement de travail qui vient d’être faite dans ce chapitrecouvre l’essentiel des connaissances nécessaires pour utiliser les programmes qui vontêtre présentés dans les prochains chapitres, et à en écrire de nouveaux.

Chacun des chapitres qui suivent comprend un certain nombrede programmes quiy sont détaillés, sont directement utilisables et peuvent également être modifiés pourles adapter à d’autres besoins. Chaque chapitre correspondà un sous-répertoire durépertoire d’installation (C:\PPL ou ~/PPL ). Pour pouvoir exécuter comme indiquéles différents programmes qui y sont présentés, il est donc nécessaire de modifier lerépertoire de travail en conséquence.

Si vous souhaitez modifier les programmes présentés, il suffit pour cela de les ou-vrir à l’aide d’un éditeur commeScite, de modifier le contenu du code, et d’enregistrerles modifications.

Si vous souhaitez créer un nouveau programme, il suffit de créer un nouveau fichiertexte (par exemple en utilisant le menuFile>New de Scite, d’y saisir le code, et del’enregistrer (en lui donnant l’extension.pl ), en prenant soin de bien sélectionner lerépertoire où il sera placé.

La façon la plus efficace de s’organiser est la suivante : avoir un éditeur ouvertavec le code du programme et un terminal dans lequel tester leprogramme. La miseau point d’un programme consiste alors en une série d’allers-retours entre ces deuxfenêtres pour le modifier et tester son fonctionnement.

Page 104: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

112

Page 105: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

CHAPITRE 3

Les bases du langage Perl

3.1. Quelques principes du langage Perl

Perl (Practical Extraction and Report Language) est un langage impératif issu delangages tels que Fortran, C, etc. Il a été spécialement conçu pour la manipulation detextes dans le cadre de l’administration des systèmes (gestion de fichiers, recherche etmodifications de données de type texte). Ses principales fonctionnalités en font doncun candidat de choix pour le travail sur tout type de données linguistiques. Principale-ment, Perl est très efficace dans le parcours de fichiers textes, la recherche, l’extractionet la modification de segments de textes, et plus généralement tout traitement sur leschaînes de caractères. Perl est à ce sujet célèbre pour la puissance de ses expressionsrégulières (voir chapitre 4), et est même devenu une référence en la matière.

Perl est un langageinterprété, et non compilé. Les conséquences de cet état defait sont qu’il n’est pas nécessaire, pour exécuter un programme, que celui-ci ait étémis sous un format binaire en code machine. Un programme Perln’est par contreutilisable que par le biais d’un interpréteur, c’est-à-dire un programme externe quidoit être installé localement sur la machine. La contrepartie est qu’un programmePerl est utilisable tel quel sur tout type de système d’exploitation (Windows, Unix,MacOS). Ce statut interprété implique que l’on parle également de « scripts » Perlau lieu de programmes, réservant ce dernier terme aux codes développés dans deslangages compilés.

De façon plus pratique, le langage Perl est un langage relativement récent (la toutepremière version date de 1987), et a bénéficié des années d’expérience accumulées aufil de l’histoire des langages de programmation. Ses concepteurs, R. Schwartz et L.Wall, ont ainsi voulu le rendre plus proche du langage naturel que ses prédécesseurs.Cette volonté se traduit en Perl par certaines caractéristiques uniques : sa souplesse

113

Page 106: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

114 Perl pour les linguistes

syntaxique, la grande polysémie de ses unités (variables non typées) et la polymor-phie de ses fonctions, la notion d’ellipse (ou travail sans variables) entre autres. Mal-heureusement, cette souplesse a été atteinte au détriment de ce que l’on est en droitd’attendre, en matière de correction de code, de la part de l’interpréteur Perl. Puisquede nombreuses expressions sont permises, peu d’erreurs de syntaxe seront repéréescomme telles, ou correctement analysées. Le langage Perl nécessite donc, lors de sonapprentissage, une grande rigueur et des précautions dans l’élaboration du code. Lamaîtrise grandissant toutefois, les spécialistes de Perl apprécient d’autant plus cettesyntaxe peu rigoureuse, et vont même jusqu’à développer leur propre style voire, pourles plus fanatiques, à écrire de la poésie en Perl.

Les sections qui suivent ont pour but de permettre au lecteurde décrypter les prin-cipaux éléments des programmes proposés dans le reste de l’ouvrage. Cette présen-tation s’appuie sur un ensemble de programmes simples sur lethème de la flexionnominale et verbale. A l’inverse des programmes présentés dans les chapitres sui-vants, les programmes de ce chapitre ne permettent pas de résoudre des problèmescourants qui se posent au linguiste travaillant sur des données informatisées, mais ontavant tout un but pédagogique.

Pour les lecteurs souhaitant aborder directement les programmes des chapitres sui-vants, l’annexe A5 contient une liste des principales notions du langage accompagnéede renvois vers les parties de l’ouvrage qui les détaillent (et principalement le présentchapitre).

3.2. Premier programme Perl

Un programme est untexteécrit dans un langage de programmation, en Perl dansle cas présent, permettant de réaliser différentes opérations. Par certains aspects, ilressemble à un texte en langue naturelle : il est écrit avec des « mots » qui s’organisenten phrases selon une grammaire particulière.

Le premier programme que nous présentons permet de fléchir les noms masculinsréguliers, c’est-à-dire ceux qui forment leur pluriel par ajout d’un s final (listing 3.1,page 114).

Listing 3.1 – flex-nom-masc.plPremier programme Perl : flexion d’un nom masculin

1 use strict;2 use locale;3

4 my $nom;5 my $pluriel;6

Page 107: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Les bases de Perl 115

7 print "Entrez un nom commun masculin singulier :";8 $nom = <STDIN>;9 chomp($nom);

10

11 $pluriel = $nom . "s";12 # Et tant pis pour les pluriels irréguliers !13

14 print "Les flexions de \"", $nom, "\" sont :\n";15 print "un ", $nom, "\n";16 print "des ", $pluriel, "\n";

Ligne de commande :perl flex-nom-masc.pl

3.2.1. Lancement et déroulement du programme

Pour pouvoir lancer ce programme, il est nécessaire de disposer d’un terminal(commePPLtermsous Windows). Il faut ensuite modifier le répertoire de travail pourse placer dans celui qui contient le fichierflex-nom-masc.pl: la commande pour cefaire est :

cd 03.Bases

On lance alors le programmeflex-nom-masc.plen tapant dans le terminal la com-mandeperl flex-nom-masc.pl (suivie d’une frappe sur la touche « Entrée »).La procédure est détaillée en section 2.5 (page 95).

L’exécution du programme donne à l’écran le résultat suivant :

Entrez un nom commun masculin singulier :

Le programme se fige ensuite et attend que l’utilisateur ait entré une chaîne decaractères terminée par une frappe de la touche « Entrée ». Supposons que celui-citape le motlapin, le résultat suivant sera alors affiché :

Les flexions du nom "lapin" sont :

Singulier : un lapin

Pluriel : des lapins

Puis le programme s’arrête et le shell attend la prochaine ligne de commande.Ce programme est bien entendu très limité d’un point de vue deson traitement, et ilproduira des résultats erronés dans bien des cas quand le pluriel ne se fabrique pasaussi simplement. Par exemple, il donnera pourcheval: des chevalset pourours: desourss.

Page 108: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

116 Perl pour les linguistes

On peut décrire informellement le fonctionnement du programme de la manièresuivante :flex-nom-masc.plcommence par afficher une invite pour indiquer qu’il at-tend que l’utilisateur lui fournisse une donnée. Il reçoit alors une chaîne de caractèresqu’il note dans une variable et dont il se sert pour calculer sa forme au pluriel. Il afficheensuite la valeur entrée et la forme plurielle calculée, le tout complété par quelqueschaînes de caractères constantes destinées à faciliter la compréhension de ces résultats.

3.2.2. Accès au code

Le texte qui compose le code du programme est visualisable etmodifiable à l’aided’un éditeur de texte (commeSciTE, voir paragraphe 2.7.2, page 103). Il suffit eneffet d’utiliser un tel outil et d’ouvrir le fichier contenant le code source (iciflex-nom-masc.pl) pour pouvoir l’examiner.

La modification d’un programme existant, ou l’écriture d’unnouveau programmepasse également par l’utilisation d’un éditeur de texte. Dès que le code a été modifié,et le fichier enregistré, le nouveau programme est directement utilisable de la mêmemanière qu’un programme existant. Nous allons maintenant regarder précisément lecontenu du code de ce premier programme.

3.2.3. Description du code

Le programmeflex-nom-masc.plest composé de 16 lignes de texte. Parmi ceslignes, 4 sont vides (n° 3, 6, 10 et 13) et permettent d’aérer le texte et de faciliter salecture. Ces lignes vides délimitent cinq parties qui sont détaillées ci-dessous : un en-tête, des déclarations de variables, une phase de lecture dedonnées, une de traitementet une d’écriture des résultats.

Le tableau ci-dessous indique le rôle et le statut des différentes lignes du pro-grammeflex-nom-masc.pl.

Entête1 use strict; Formule figée de début de programme2 use locale; Formule figée de début de programme3 Ligne vide

Déclaration des variables4 my $nom; Déclaration de la variable$nom qui ser-

vira à stocker en mémoire le nom entré parl’utilisateur

5 my $pluriel; Déclaration de la variable$pluriel quiservira à stocker la forme au pluriel du nom

6 Ligne vide

Page 109: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Les bases de Perl 117

Lecture des données7 print "Entrez un nom commun

masculin singulier : ";Affichage dans le terminal du messaged’accueil du programme

8 $nom = <STDIN>; Lecture du nom entré par l’utilisateur etstockage de celui-ci dans la variable$nom

9 chomp($nom); Suppression du caractère de fin de lignedans la variable$nom

10 Ligne vide

Traitement11 $pluriel = $nom . "s"; Calcul de la chaîne correspondant au plu-

riel par concaténation de la chaîne entréepar l’utilisateur et d’un ‘s’

12 #Et tant pis pour lespluriels irréguliers !

Commentaire ignoré par l’interpréteur

13 Ligne vide

Affichage des résultats14 print "Les flexions de \"",

$nom, "\" sont :\n";Affichage d’une ligne de texte constituéedu mot entré par l’utilisateur, entre guille-mets, au sein d’une phrase

15 print "un ", $nom, "\n"; Affichage du nom au singulier, précédé deun

16 print "des ", $pluriel, "\n"; Affichage du nom au pluriel, précédé dedes

3.2.3.1.Entête : lignes 1 et 2

Ces deux premières lignes se retrouveront systématiquement en tête de tous lesprogrammes présentés dans cet ouvrage. Elles permettent simplement de modifier lé-gèrement le comportement de l’interpréteur Perl. Nous les détaillerons par la suite.Notons pour l’instant que ces lignes, comme toutes celles dece programme, sont ter-minées par des points-virgules.

3.2.3.2.Déclaration des variables : lignes 4 et 5

Cette étape est également un préliminaire du programme à proprement parler. Sonseul but est de prévenir l’interpréteur Perl que la suite du code va utiliser des variables,c’est-à-dire des étiquettes pour les données qui seront manipulées par le programme.Ce programme utilise deux variables :$nom qui correspond au nom entré par l’uti-lisateur, et$pluriel qui correspond à la forme du pluriel. Ces deux variables sontprévues pour contenir des chaînes de caractères, c’est-à-dire des valeurs simples (ap-peléesscalairesen Perl) : leur nom doit commencer par le symbole$, mais la sé-quence de lettres qui suit est arbitraire. Ces variables vont apparaître dans la suite duprogramme, mais une même variable doit toujours être appelée de la même manière.Une variable peut être identifiée par n’importe quelle séquence de lettres (non accen-tuées), et utilisant éventuellement des chiffres ou le caractère souligné ‘_’.

Page 110: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

118 Perl pour les linguistes

Les lignes 4 et 5 n’ont comme seul but que de déclarer quelles sont les variables quiseront utilisées par la suite. Le mot-clémy qui les précède indique cette déclaration.

3.2.3.3.Lecture des données : lignes 7 à 9

Cette étape est en fait la première dont le comportement est visible lors de l’exécu-tion du programme. C’est grâce à ces instructions que le programme va communiqueravec son utilisateur, en affichant un message l’invitant à entrer un nom, puis en sto-ckant dans une variable le nom en question pour son traitement dans l’étape suivante.Chacune de ces trois lignes effectue une action particulière, détaillée ici :

1) [ligne 7] l’affichage d’un message demandant à l’utilisateur de fournir un mot.Il est réalisé au moyen de la commandeprint qui écrit sur le flux de sortie standard lachaîne de caractères qui lui est fournie en paramètre (voir «Affichage des résultats »en page 119). Ce paramètre est une constante composée d’une séquence de caractèresdélimitée par des guillemets anglais. Ces guillemets ne font pas partie de la chaîne decaractères et ne sont donc pas imprimés ;

2) [ligne 8] la lecture proprement dite de la chaîne de caractères se fait sur le fluxd’entrée standard (STDIN) en utilisant l’opérateur<>. L’expression<STDIN> permetde lire une ligne sur le flux d’entrée. Dans le programmeflex-nom-masc.pl, le résultatde cette lecture est stocké dans la variable$nom par l’intermédiaire de l’affectation=. Cette opération affecte à la variable$nom, qui se trouve à gauche de l’opérateur, lavaleur correspondant à l’expression qui se trouve à sa droite, en l’occurrence la lignelue ;

3) [ligne 9] la suppression du caractère de fin de ligne. Lors de l’exécution duprogramme, l’utilisateur doit taper les lettres du mot qu’il souhaite fléchir suivies d’unretour à la ligne, obtenu en appuyant sur la touche « Entrée ».Cette touche saisit enfait un caractère non affichable mais qui constitue le dernier caractère de la ligne lue.Ainsi, si l’utilisateur entre le motlapin, la ligne lue par l’instruction<STDIN> seracomposée de 6 caractères :

l a p i n \n

où \n est le caractère qui représente la fin de ligne saisievia la touche « Entrée ». Cedernier caractère ne fait pas logiquement partie du mot que l’utilisateur souhaite voirtraiter. Il s’agit seulement du séparateur qui délimite leslignes lues par<STDIN>. Ondoit donc le supprimer pour que la variable$nom ne contienne que les caractères quicomposent la forme de citation du nom. On utilise pour cela lafonctionchomp quienlève les retours à la ligne qui se trouvent à la fin de la chaîne de caractères qui luiest fournie en paramètre (en l’occurrence$nom).

3.2.3.4.Traitement : lignes 11 et 12

Traitement. La flexion d’un nom masculin singulier régulier réalisée parflex-nom-masc.plest relativement simple. La forme de citation constitue la forme au singu-lier et celle du pluriel est obtenue en lui ajoutant uns. Le traitement réalisé com-porte deux opérations : le calcul de la forme au pluriel puis son stockage dans la

Page 111: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Les bases de Perl 119

variable$pluriel . La première opération est réalisée au moyen de l’expression$nom . "s" qui permet d’appliquer l’opérateur de concaténation ‘. ’ à deux opé-randes1 : la valeur contenue dans la variable$nomd’une part et la chaîne de caractèresconstante"s" de l’autre. La chaîne de caractères résultante constitue lavaleur de l’ex-pression, par exemple,"lapins" si $nomcontient"lapin" . La seconde opérationest l’affectation de ce résultat à la variable$pluriel . Elle utilise l’opérateur= quipermet de stocker dans la variable indiquée par son opérandede gauche la valeur del’expression qui constitue son opérande de droite.

L’instruction qui calcule le pluriel est complétée par une ligne de commentaire(ligne 12) qui est ignorée pas l’interpréteur Perl. Un commentaire est un texte librequi commence par le caractère# et se termine à la fin de la ligne. Le commentaire sertici à rappeler à l’auteur du programme qu’un grand nombre de cas ne sont pas traitéscorrectement.

3.2.3.5.Affichage des résultats : lignes 14 à 16

La dernière partie du programme affiche les résultats du programme sur troislignes, au moyen de trois instructionsprint . La première (ligne 14) affiche le textequi introduit les résultats. Elle a trois arguments :

– une chaîne de caractères constante"Les flexions de \"" ;

– la variable$nom;

– une seconde chaîne de caractères constante"\" sont :\n" .

La deuxième instruction (ligne 15) permet d’écrire à l’écran la première ligne de résul-tat, comprenant le nom entré par l’utilisateur au singulier, précédé de l’article indéfiniun. Elle comporte trois arguments :

– une chaîne de caractères constante"Singulier : un " ;

– la variable$nom;

– une seconde chaîne de caractères constante"\n" .

La troisième instruction effectue l’affichage de la forme aupluriel précédée del’article des, en suivant le même schéma que la ligne 15.

Dans le texte du programme, les arguments deprint sont écrits immédiatementaprès le nom de la fonction puis un espace. Ils sont séparés les uns des autres pardes virgules. Lors de l’exécution du programme,print affiche ses arguments l’unaprès l’autre dans le flux de sortie standard. Les chaînes de caractères constantes sontaffichées telles quelles.

1. On appelle opérande les paramètres d’un opérateur.

Page 112: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

120 Perl pour les linguistes

Les guillemets doubles (" ) qui se trouvent au début et à la fin des chaînes de carac-tères constantes sont des délimiteurs : ils ne font pas partie de ces chaînes et ne sontpas affichés. Leur rôle est d’indiquer les éléments qui seront affichés, par oppositionà ceux qui servent à structurer le programme. C’est notamment le cas des espaces :en dehors des guillemets, ils séparent les différentes unités du code ; à l’intérieur desguillemets ce sont des caractères qui seront affichés en sortie. Il est donc importantqu’il y ait un espace avant le guillemet fermant aprèsun : sans lui, le résultat affichéserait (pour la chaînelapin entrée par l’utilisateur) :

Singulier : unlapin

Par contre, les espaces situés en dehors des guillemets n’ont pas une telle importancequand ils entourent les séparateurs des éléments du programme (virgules, guillemets,points-virgules, etc.). Leur rôle est simplement de faciliter la lecture du code.

Pour les variables comme$nom la fonctionprint affiche la valeur qui y est sto-ckée. Si par exemple$nomcontient"lapin" , print affichera «lapin » et non pas« $nom».

Une particularité des deux chaînes de caractères constantes en ligne 14 est qu’ellescontiennent des guillemets anglais (voir paragraphe 3.2.1, page 115). Or en Perl, cecaractère est utilisé comme délimiteur des chaînes de caractères. Il ne faut donc pasqu’au moment de l’exécution du programme, l’interpréteur qui analyse cette instruc-tion considère les guillemets contenus dans la chaîne commeétant des délimiteursindiquant la fin de cette dernière. Pour signaler ces guillemets comme n’étant pas desdélimiteurs, le programmeur doit les faire précéder du caractère d’échappement\ (oubarre oblique arrière oubackslash). Ainsi, à l’intérieur d’une chaîne délimitée par desguillemets,\" représente le caractère guillemet.

Enfin, ces trois instructions indiquent que le texte doit être affiché sur trois lignesdistinctes. Les dernières chaînes constantes de chacune contiennent en effet le carac-tère de fin de ligne\n . Ce caractère indique àprint qu’il doit imprimer la suite desrésultats sur la ligne suivante du flux de sortie standard. Ilpeut apparaître n’importeoù dans une chaîne de caractères : le programmeur peut (et doit) ainsi gérer lui-mêmeles retours à la ligne à la fois au niveau des entrées (fonction chomp) que des sorties(écriture d’un\n chaque fois qu’il faut revenir à la ligne).

3.3. Syntaxe de base de Perl

Au vu de ce premier programme, il est désormais possible de préciser les notionsprincipales de la syntaxe du langage Perl.

Les unités de plus haut niveau dans un programme Perl sont lesblocs d’instruc-tions. (Les blocs correspondraient dans un texte aux paragraphes ou aux sections.) Le

Page 113: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Les bases de Perl 121

programmeflex-nom-masc.plest exceptionnellement simple du point de vue de sastructure : il comporte un seul bloc. Les blocs sont à leur tour composés d’instructionsséparées par des points-virgules. (Les instructions correspondraient aux phrases d’untexte.) Habituellement, chaque instruction est écrite surune ligne, même si la miseen page d’un programme n’a aucune importance pour l’interpréteur. Les instructionsdu programmeflex-nom-masc.plsont toutes des instructions simples dans la mesureoù aucune structure de contrôle n’est utilisée. Des programmes comportant plusieursblocs et des instructions complexes sont présentés dans lessections 3.5 et 3.7.

Une grande partie de la syntaxe d’un langage de programmation régit la bonneformation des instructions. En Perl, les instructions sontcomposées :

– de mots-clés2, de noms de fonctions prédéfinies, de noms de flux standard...Dansflex-nom-masc.pl, les éléments de ce premier groupe sont :use; strict ; locale; my ;print ; STDIN ; chomp. Ces unités doivent être connues par le programmeur et uti-lisées telles quelles. Les formes qui permettent de les évoquer et leurs interprétationssont fixées une fois pour toutes ;

– de valeurs comme"s" , "Les flexions de " ou "Singulier :un " . Ces trois valeurs sont des chaînes de caractères. Mais il existe d’autres typesde valeurs en Perl : entier, réel, tableau de scalaires, hachage... Toutes les valeursutilisées dans le programmeflex-nom-masc.plsont des chaînes de caractères. Lesvaleurs se présentent dans un programme soit sous la forme deconstantes comme"Singulier : un " soit comme le résultat d’un calcul comme1 + 1 pour lavaleur entière2. Les valeurs utilisées dans un programme sont définies par lepro-grammeur en fonction de ses besoins ;

– de variables, comme$nomet$pluriel , qui représentent des données dont onne connaît pas les valeurs exactes lors de l’écriture du programme. Lors de l’exécu-tion du programmeflex-nom-masc.pl, les variables$nomet$pluriel contiendrontrespectivement le nom que l’on devra fléchir (sa forme de citation) et sa forme aupluriel. Ces deux valeurs seront donc des scalaires, en l’occurrence, des chaînes decaractères. En Perl, les variables sont typées par le type des valeurs qu’elles peuventcontenir : scalaire, liste ou hachage. Le type d’une variable est indiqué par le premiercaractère de leur nom. Ainsi, le nom d’une variable scalairedébute par un$, celuid’une liste par un@et celui d’un hachage par un%. A la différence des mots-cléset des noms de fonctions prédéfinies, le choix des identificateurs de variables, leursnoms, est laissé à la discrétion du programmeur. On aurait par exemple pu décider denommer$substantif la variable qui contient la forme au singulier dans le pro-grammeflex-nom-masc.pl. Dans ce cas, toutes les occurrences de$nom dans le textedu programme seraient remplacées par$substantif , sans que cela n’entraîne au-cune conséquence sur le fonctionnement du programme;

2. Les mots-clés sont également appelés « mots réservés ».

Page 114: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

122 Perl pour les linguistes

– d’opérateurs comme ‘. ’, +, etc., qui permettent de réaliser des opérations surdes données, ces dernières pouvant être représentées par des constantes ou par desvariables. Par exemple, l’opérateur ‘. ’ (point) permet de concaténer deux chaînes decaractères, l’opérateur+ permet d’additionner deux valeurs numériques. Il existe éga-lement en Perl des opérateurs plus particuliers comme l’affectation= ou l’opérateurde lecture de ligne<>. Les opérateurs constituent en réalité un sous-ensemble desfonctions prédéfinies dont le nom n’est généralement pas alphabétique et qui sont in-fixés lorsqu’ils sont binaires, les fonctions étant quant à elles toujours préfixées à leursarguments. Les noms des opérateurs de Perl sont définis par lelangage.

Du point de vue de leur forme, les instructions d’un programme Perl peuvent êtreréparties en trois groupes :

1) les instructions qui ne servent qu’à prévenir l’interpréteur Perl, et qui générale-ment se situent dans l’entête du programme. Parmi celles-ci, il y a les utilisations demodules (paruse) et les déclarations de variables (parmy) ;

2) les instructions qui effectuent une action sur les données, et qui commencentpar le nom de cette action. C’est le cas de l’affichage de données (parprint ) ou encorede leur modification (comme la suppression des fins de lignes parchomp) ;

3) les instructions qui calculent des valeurs nouvelles à partir d’autres déjà connues(comme en ligne 11 du listing 3.1, page 114). Ces instructions mettent habituelle-ment en jeu l’opérateur d’affectation= qui permet de stocker une valeur (son opé-rande droite) dans une variable (son opérande gauche). La valeur affectée est soit uneconstante, une autre variable, ou encore une expression de calcul. Il est possible d’af-fecter une nouvelle valeur à une variable qui en contenait déjà une, mais dans ce casla valeur précédente est perdue, et remplacée par la nouvelle.

3.4. Version simplifiée et raccourcie du premier programme

Le programmeflex-nom-masc.plpeut être à la fois simplifié dans son traitementet dans sa syntaxe, comme nous allons le voir en présentant une seconde version quipermet d’obtenir exactement le même comportement.

Du point de vue de la syntaxe, il est notamment possible :

– de déclarer les variables au fur et à mesure que l’on s’en sert, en plaçant le mot-clé my devant la première occurrence de chaque variable ;

– de supprimer les parenthèses autour du paramètre d’une fonction lorsque celle-cin’en a qu’un seul (comme c’est le cas pourchomp) ;

– de regrouper les différentes chaînes à afficher en n’utilisant qu’une seule fois lafonctionprint .

Ces conventions seront désormais celles utilisées pour lesprogrammes présentésdans le reste de l’ouvrage.

Page 115: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Les bases de Perl 123

Du point de vue du traitement, le calcul du pluriel d’un nom masculin régulierétant trivialement simple, il aurait également été possible d’imprimer directement cetteforme sans la calculer explicitement au préalable. C’est cequi est réalisé dans la va-rianteflex-nom-masc2.pldu programmeflex-nom-masc.plprésenté en listing 3.2. Cesecond programme ne contient plus la variable$pluriel qui n’est utilisée dansflex-nom-masc.plque pour imprimer la forme du pluriel du nom à fléchir.

Listing 3.2 – flex-nom-masc2.plVariante simplifiée deflex-nom-masc.pl: flexion d’un nom masculin

1 use strict;2 use locale;3

4 print "Entrez un nom commun masculin singulier : ";5 my $nom = <STDIN>;6 chomp $nom;7 print "Les flexions de \"", $nom, "\" sont :\nun ",8 $nom, "\ndes ", $nom, "s\n";

Ligne de commande :perl flex-nom-masc2.pl

Ce programme fonctionne exactement commeflex-nom-masc.pl. Il s’en distinguecependant par le fait qu’il ne comporte pas de phase de traitement. Le calcul de laforme du pluriel est réalisé de façon implicite lors de l’impression de celle-ci (ligne 6),en affichant uns constant immédiatement après la forme correspondant au singulier.

La seule instructionprint utilisée pour afficher l’ensemble des résultats comportemaintenant 7 arguments : 4 constantes et 3 variables. Les finsde ligne (\n ) y sontprésentes dans les constantes, et assurent un affichage identique à celui de la versionprécédente. Ce regroupement a bien entendu une incidence sur la longueur des lignesdu code. Cette instruction d’affichage unique est ainsi troplongue pour être affichéecorrectement sur une seule ligne de code. Elle a donc été découpée en deux lignes (eninsérant un retour à la ligne en cours d’instruction lors de la frappe du programme).Ceci ne pose aucun problème à Perl pour l’interprétation du programme, tout en facili-tant la lecture du programme. Il est toutefois d’usage d’indiquer qu’une ligne de codeest la suite d’une instruction commencée à la ligne précédente en la décalant (avec desespaces en début de ligne) vers la droite, comme c’est le cas pour la ligne 6.

Nous allons maintenant voir comment réaliser des traitements plus complexes, cequi va nécessiter l’utilisation de structures syntaxiquesplus élaborées dans le code,appelées également structures de contrôle.

3.5. Structures de contrôle : instructions conditionnelles

Un langage de programmation comme Perl comporte deux types d’instructions :des instructions simples comme toutes celles qui sont utilisées dans les programmes

Page 116: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

124 Perl pour les linguistes

flex-nom-masc.plet flex-nom-masc2.plet des instructions complexes formées aumoyen de structures de contrôle. Ces structures sont elles-même de deux types : condi-tionnelle et boucle. Elles permettent d’assujettir l’exécution ou l’itération d’un blocd’instructions à une condition. (Le bloc d’instructions est une suite d’instructions dé-limitée par des accolades).

La structure de contrôle la plus simple est la conditionnelle. Elle est utilisée dansle programme présenté en listing 3.3 (page 124) pour fléchir des noms masculins ouféminins en fonction du genre indiqué par l’utilisateur.

Listing 3.3 – flex-nom-mf.plExemple d’utilisation des conditionnelles : gestion du genre pour la flexion des noms

1 use strict;2 use locale;3

4 print "Entrez un nom singulier : ";5 my $nom = <STDIN>;6 chomp $nom;7

8 print "Quel est son genre (f ou m) ? ";9 my $genre = <STDIN>;

10 chomp $genre;11

12 my $article;13 if ( $genre eq "f" ) 14 $article = "une";15 16 else 17 if ( $genre eq "m" ) 18 $article = "un";19 20 else 21 die "Veuillez entrer f ou m pour le genre du nom !\n";22 23 24

25 print "Les flexions de \"", $nom, "\" sont :\n", $article, " " ,26 $nom, "\n", "des ", $nom,"s\n";

Ligne de commande :perl flex-nom-mf.pl

Exemple de déroulement :(les chaînes tapées par l’utilisateur sont en gras)Entrez un nom singulier : lapin

Quel est son genre (f ou m) ? m

Les flexions de "lapin" sont :

un lapin

des lapins

Page 117: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Les bases de Perl 125

Second Exemple :Entrez un nom singulier : vache

Quel est son genre (f ou m) ? f

Les flexions de "vache" sont :

une vache

des vaches

Ce programme permet de fléchir à la fois les noms masculins et féminins réguliers,c’est-à-dire ceux dont le pluriel est formé par l’ajout d’uns à la fin de la forme ausingulier. Le calcul du pluriel est réalisé de la même façon que dansflex-nom-masc2.pl(la ligne 26 du listing 3.3 est identique à la ligne 8 du listing 3.2). Du point de vuede son déroulement, le programme demande à l’utilisateur delui indiquer le genre dumot à fléchir puis utilise cette information pour choisir le déterminant approprié.

La lecture du mot à fléchir et de son genre est réalisée comme dans les programmesprécédents. Une variable$genre est utilisée pour conserver la valeur donnée parl’utilisateur. La partie centrale du programme est constituée des lignes 12 à 23 quel’on peut gloser comme suit :

« si $genre contient la chaîne"f" , on place la chaîne"une" dans la variable$article ; si $genre contient la chaîne"m" , on place"un" dans$article ;dans tous les autres cas, on affiche un message d’erreur et le programme s’arrête ».

Cette opération complexe est réalisée au moyen de deux instructions condition-nelles3 if ... else ...imbriquées. La première comporte :

1) une condition($genre eq "f") qui suit immédiatement le mot-cléif(ligne 13). Cette condition utilise l’opérateur de comparaison de chaîneseq . Elle vautVRAI si la valeur de$genre est égale à"f" et FAUX dans tous les autres cas ;

2) un premier bloc d’instructions qui permet d’affecter"une" à $article(ligne 14). Les instructions de ce bloc ne sont exécutées quesi la condition précé-dente est vraie ;

3) un second bloc constitué des lignes 16 à 23, introduit par le mot-cléelse. Lesinstructions contenues dans ce bloc ne sont exécutées que sila condition précédenteest fausse. Ce bloc est lui-même une conditionnelleif ... else ...qui se compose :

a) d’une condition($genre eq "m") qui suit immédiatement le mot-cléif(ligne 17). Cette condition vaut VRAI si la valeur de$genre est égal"m" et FAUXdans tous les autres cas ;

b) d’un bloc d’instructions qui permet d’affecter"un" à $article(ligne 18) ;

3. La mise en page de ces conditionnelles a été aménagée pour faciliter leur présentation.

Page 118: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

126 Perl pour les linguistes

c) d’un dernier bloc introduit par le mot-cléelsequi affiche un message d’er-reur et stoppe le programme (ligne 21). Ce bloc d’instruction n’est exécuté que lors-qu’aucune des deux conditions préalables n’a été remplie (autrement dit, le genredonné par l’utilisateur n’est nif ni m). L’arrêt du programme est réalisé au moyende la fonction prédéfiniedie. Cette instruction met une finimmédiateau programmeen cours, et affiche le message qui est précisé en paramètre (Veuillez entrer f ou mpour le genre du nom !). Cette fonction est généralement utilisée dans les cas où unévénement extérieur au programme compromet la suite de son déroulement. Ici, parexemple, le fait que l’utilisateur n’ait entré nif ni mcomme genre ne permet pas auprogramme de prendre une décision pour l’affichage final des résultats. La fin préma-turée du programme ainsi déclenchée fait que les instructions d’affichage en fin deprogramme ne seront pas exécutées.

Une fois les différents blocs conditionnels terminés (par les accolades fermantesdes lignes 22 et 23), les instructions d’affichage ont lieu, et exploitent le contenu de lavariable$article .

Lors de la présentation du code d’un programme contenant desblocs d’instruc-tions, il est d’usage de procéder à uneindentation, c’est-à-dire à un décalage vers ladroite des instructions situées dans un bloc. Cette disposition permet d’identifier faci-lement les blocs sans avoir à rechercher les accolades qui les délimitent, ce qui peutêtre difficile dans des programmes plus longs. Cette indentation n’a d’importance quepour le lecteur d’un tel programme : l’interpréteur Perl n’en tient pas compte. L’in-dentation est généralement réalisée automatiquement lorsde la saisie du code dans unéditeur.

En résumé, une structure conditionnelle comporte donc une condition et deuxblocs d’instructions. La condition est délimitée par des parenthèses et les blocs pardes accolades. Elles sont appeléesconditionnellesparce que la valeur de vérité de lacondition (VRAI ou FAUX) détermine le bloc qui sera exécuté :le premier bloc si elleest vraie et le second si elle est fausse.

L’imbrication d’une instruction complexe dans une autre est courante en Perl. Elleest prévue par la syntaxe du langage : une instruction complexe peut apparaître à toutendroit où une instruction simple peut être utilisée.

REMARQUE.– Déclaration de variables et blocs d’instructions.Contrairement auxvariables$nom et $genre , la variable$article n’est pas déclarée au moment desa première utilisation, mais en-dehors du bloc conditionnel. Ceci est nécessaire carcette variable va être utilisée à la fois dans les blocs conditionnels imbriqués (pour sonaffectation) et dans les instructions situées dans le bloc principal (pour son affichage).Or, la visibilité d’une variable (également appeléeportée) est limitée au bloc danslequel elle est déclarée : il est donc nécessaire de placer l’instructionmy $article;avant les blocs conditionnels. Toutefois, la portée d’une variable comprend les blocs

Page 119: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Les bases de Perl 127

situés à l’intérieur de celui où elle est déclarée.$article étant déclarée dans le blocprincipal du programme, elle porte le nom de variableglobale.

Il faut également noter que lors de la déclaration d’une variable parmy, cettedernière estinitialisée, même si on n’utilise pas une affectation explicite. Une va-riable scalaire reçoit ainsi, lors de sa déclaration, une valeur indéfinie(si on afficheson contenu, ce sera la chaîne vide).

3.5.1. Simplification des conditionnelles imbriquées par elsif

Il est possible de simplifier la structure générale du programmeflex-nom-mf.plen limitant l’imbrication des blocs conditionnels. Cette simplification est possible enfusionnant les deux mots-cléselseet if par elsif. C’est ce qui est fait dans le pro-grammeflex-nom-mf2.plprésenté en listing 3.4 dont le comportement est strictementidentique au précédent.

Listing 3.4 – flex-nom-mf2.plVersion simplifiée deflex-nom-mf.plutilisantelsif

1 use strict;2 use locale;3

4 print "Entrez un nom singulier : ";5 my $nom = <STDIN>;6 chomp $nom ;7

8 print "Quel est son genre (f ou m) ? ";9 my $genre = <STDIN>;

10 chomp $genre;11

12 my $article;13 if ( $genre eq "f" ) 14 $article = "une";15 16 elsif ( $genre eq "m" ) 17 $article = "un";18 19 else 20 die "Veuillez entrer f ou m pour le genre du nom !\n";21 22

23 print "Les flexions de \"", $nom, "\" sont :\n", $article, " " ,24 $nom, "\n", "des ", $nom,"s\n";

Ligne de commande :perl flex-nom-mf2.pl

Ce programme a exactement le même comportement queflex-nom-mf.pl.

Page 120: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

128 Perl pour les linguistes

La structure de contrôleif ... elsif ... elsepermet d’articuler trois blocs d’instruc-tions en utilisant deux conditions, ces trois blocs étant situés au même niveau hiérar-chique. Cette structure augmente la lisibilité du programme en évitant les imbricationstrop profondes. Il est possible de l’utiliser avec autant deblocs introduits parelsif quenécessaire. Ce serait par exemple le cas si l’on avait plus dedeux genres à prendre encompte.

Il est également possible de ne définir qu’un seul bloc d’instruction, en omettantle bloc correspondant àelse. Dans ce cas, si la condition n’est pas remplie, aucuneinstruction spécifique n’est exécutée et le programme passeaux instructions situéesaprès la structure conditionnelle.

3.5.2. Syntaxe des conditions

Maintenant que la structure syntaxique des instructions conditionnelles a été pré-sentée, il est important de se pencher sur la syntaxe qui régit les conditions. Une condi-tion est une expression de calcul dont le résultat est une valeur de vérité (VRAI ouFAUX). On parle également d’expression booléenne. Une expression booléenne estpar exemple celle qui correspond à la comparaison de deux valeurs. C’est le cas pourle programmeflex-nom-mf.pl, où l’on compare le contenu de la variable$genreavec une chaîne constante ("m" ) en utilisant l’opérateur de comparaison de chaîneseq .

3.5.2.1.Opérateurs de comparaison

Il existe en Perl d’autres opérateurs de comparaison dont voici la liste :

– égalité numérique :== ;

– égalité de chaîne :eq (pourequal) ;

– différence numérique :!= ;

– différence de chaîne :ne (pournot equal) ;

– inégalité stricte de nombre :< (infériorité) et> (supériorité) ;

– inégalité de chaînes selon l’ordre lexicographique :lt (infériorité ; pour lessthan) etgt (supériorité ; pourgreater than) ;

– inégalité non stricte numérique :<= et >= ;

– inégalité non stricte selon l’ordre lexicographique :le (pour less or equal) etge (pourgreater or equal).

La distinction qui doit être faite entre comparaison numérique et comparaison dechaînes est très importante. Comme Perl ne fait pas de différence explicite entre cesdeux types de valeurs (les deux étant pour Perl des valeursscalaires), le choix del’opérateur doit être fait avec soin. La distinction est visible dans les exemples sui-vants :

Page 121: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Les bases de Perl 129

– 1 et 01 sont numériquement égaux (1 == 01 est VRAI, mais différents si onles considère comme des chaînes de caractères (1 eq 01 est faux) ;

– 11 est situé numériquement après2 (11 >= 2 est VRAI), mais lexicographi-quement avant (11 lt 2 est VRAI), puisque le caractère"1" est situé avant"2"dans l’ordre lexicographique (commeaaest situé avantb) ;

– vacheet lapin sont différents en tant que chaînes ("vache" ne "lapin"est VRAI) mais identiques en tant que valeurs numériques"vache" == "lapin"est VRAI). En effet, dans le cas d’une comparaison numériqueentre deux valeursne comportant aucun chiffre, Perl considère simplement queces deux valeurs sontnumériquement égales à zéro.

3.5.2.2.Connecteurs logiques

Dans certains cas, la simple comparaison entre deux valeursn’est pas suffisantepour décider de l’action qu’un programme doit effectuer. Ilpeut arriver notammentque plusieurs conditions doivent être remplies (conjonction) ou qu’une conditionparmi une liste soit suffisante (disjonction). Il est alors nécessaire de définir des condi-tions complexes en reliant des conditions élémentaires pardes opérateurs logiques.

Il est par exemple possible en utilisant une condition complexe, de fléchir correcte-ment des noms invariables dont on établit au préalable une liste. Il suffit alors, avant decalculer le pluriel, de tester si le nom à fléchir en fait partie, auquel cas la pluriel seracalculé en recopiant simplement la forme au singulier. C’est ce que fait le programmeflex-nom-invar.plprésenté en listing 3.5.

Listing 3.5 – flex-nom-invar.plExemple d’utilisation des connecteurs logiques : gestion de quelques noms invariables

1 use strict;2 use locale;3

4 print "Entrer un nom commun masculin singulier : ";5 my $nom = <STDIN>;6 chomp $nom;7

8 my $pluriel;9 if ( ($nom eq "ours") or ($nom eq "lynx") or ($nom eq "putois") )

10 $pluriel = $nom;11 12 else 13 $pluriel = $nom . "s";14 15

16 print "Les flexions de \"", $nom, "\" sont :\nun ", $nom,17 "\ndes ", $pluriel, "\n";

Ligne de commande :perl flex-nom-invar.pl

Page 122: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

130 Perl pour les linguistes

Exemple de déroulement :(les chaînes entrées par l’utilisateur sont en gras)Entrer un nom commun masculin singulier : ours

Les flexions de "ours" sont :

un ours

des ours

Second exemple :Entrer un nom commun masculin singulier : lapin

Les flexions de "lapin" sont :

un lapin

des lapins

Ce programme reprend le fonctionnement deflex-nom-masc.pl, mais une structureconditionnelle en lignes 9 à 14 permet de gérer une courte série de noms invariables.La condition de la ligne 9 est une disjonction qui s’appuie sur trois comparaisonssimples portant sur la variable$nom. Si l’un des trois noms est rencontré, la condi-tion correspondant à sa comparaison sera vraie (et les autres fausses). Dans ce cas,la condition dans son ensemble sera vraie, et le pluriel seracalculé en recopiant sim-plement la forme du nom singulier. Si aucun de ces trois noms n’est entré, toutes lesconditions élémentaires seront fausses, et la condition sera globalement fausse : lepluriel sera calculé en ajoutant uns à la forme du singulier.

Il existe trois opérateurs logiques fondamentaux :

– and (ET) qui exprime la conjonction entre deux conditions : la condition résul-tante est vraie si et seulement si les deux conditions sont vraies ;

– or (OU) qui exprime la disjonction entre deux conditions : la condition résul-tante est vraie si au moins l’une des deux conditions est vraie ;

– not (NON ou PAS) qui exprime la négation d’une condition : la condition ré-sultante est vraie si la condition est fausse.

Syntaxiquement, la condition complexe de la ligne 9 se construit en plaçant le mot-clé or entre les comparaisons élémentaires, elles-mêmes devant être placées entreparenthèses. Il est bien entendu possible de cumuler différents types de connecteurs,et de construire ainsi des expressions logiques bien plus complexes, comme ce sera lecas dans certains des programmes présentés dans cet ouvrage.

3.5.2.3.Utilisation de valeurs comme conditions

Il est possible d’utiliser directement une valeur scalairecomme condition : dans cecas aucun opérateur de comparaison n’est utilisé. Par exemple, la structure de contrôlesuivante est tout à fait légitime :if ( $test ) ...

Page 123: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Les bases de Perl 131

Dans ce cas, la valeur de vérité est obtenue directement à partir de la valeur de lavariable$test en appliquant les règles suivantes :

– la valeur numérique 0 (zéro) est FAUSSE ;

– toute valeur numérique différente de 0 est VRAIE ;

– la chaîne de caractères vide ("" ) est FAUSSE ;

– toute chaîne de caractères non vide est VRAIE ;

– toute valeur indéfinie est FAUSSE.

Cette possibilité permet notamment de raccourcir certaines conditions, en évitantde faire appel à une comparaison explicite pour les cas précédents. Par exemple, testersi une chaîne$chaine n’estpasvide peut se faire aussi bien par :if ( $chaine ne "" ) ...

que par :if ( $chaine ) ...

3.6. Structures de données

Les instructions Perl peuvent donc être simples et complexes. C’est aussi le casdes données. Les programmes présentés dans les sections précédentes n’utilisent quedes données simples, à savoir des scalaires. Mais Perl dispose également de types dedonnées plus complexes, appelées structures de données. Ilen existe principalementdeux : les tableaux et les hachages. Du point de vue fonctionnel, les deux structuressont des ensembles de données munies de méthodes permettantl’accès à ces dernières.

3.6.1. Tableaux

Dans les tableaux, les données sont stockées dans des cellules ordonnées enséquence. (Les tableaux sont également appelés « listes ».)L’accès se fait de deuxfaçons, séquentiellement selon l’ordre linéaire ou en utilisant directement le numérod’ordre dans la séquence. Comme tous les types de données, les tableaux peuvent êtresoit des constantes, soit des variables qui représentent des tableaux. Une constantede type tableau est une suite de valeurs séparées par des virgules et délimitée par desparenthèses, comme dans l’exemple suivant :

("je", "tu", "il/elle", "nous", "vous", "ils/elles")

Ce tableau de pronoms personnels sujets peut être représenté schématiquementcomme suit :

je tu il/elle nousvous ils/elles0 1 2 3 4 5

Page 124: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

132 Perl pour les linguistes

La première ligne du schéma énumère les valeurs stockées et la deuxième les indicesqui permettent d’y accéder. En Perl, les indices d’un tableau commencent toujours àzéro.

Le tableau précédent peut par exemple être utilisé dans un programme de flexionverbale, commeflex-verb.plqui est présenté en listing 3.6.

Listing 3.6 – flex-verb.plExemple d’utilisation des tableaux : la flexion des verbes

1 use strict;2 use locale;3

4 my @pronom = ("je", "tu", "il/elle", "nous", "vous", "ils/e lles");5 my @groupe1 = ("e", "es", "e", "ons", "ez", "ent" );6 my @groupe2 = ("is", "is", "it", "issons", "issez", "issent " );7

8 print "Entrez le radical d’un verbe du 1er ou du 2e groupe : ";9 my $radical = <STDIN>;

10 chomp $radical;11

12 print "Quel est le groupe du verbe (1/2) ? ";13 my $groupe = <STDIN>;14 chomp $groupe;15

16 my @flexion;17 my $infinitif;18 if ( $groupe == 1 ) 19 $infinitif = $radical . "er";20 @flexion = @groupe1;21 22 elsif ( $groupe == 2 ) 23 $infinitif = $radical . "ir";24 @flexion = @groupe2;25 26 else 27 die "Ce programme ne traite que les 1er et 2e groupes !\n";28 29

30 print "Les formes du verbe \"", $infinitif,31 "\" au présent de l’indicatif sont :\n";32

33 print $pronom[0], " ", $radical, $flexion[0], "\n";34 print $pronom[1], " ", $radical, $flexion[1], "\n";35 print $pronom[2], " ", $radical, $flexion[2], "\n";36 print $pronom[3], " ", $radical, $flexion[3], "\n";37 print $pronom[4], " ", $radical, $flexion[4], "\n";38 print $pronom[5], " ", $radical, $flexion[5], "\n";

Ligne de commande :perl flex-verb.pl

Exemple de déroulement :(les chaînes tapées par l’utilisateur sont en gras)Entrez le radical d’un verbe du 1er ou du 2e groupe : fléch

Page 125: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Les bases de Perl 133

Quel est le groupe du verbe (1/2) ? 2

Les formes du verbe "fléchir" au présent de l’indicatif sont :

je fléchis

tu fléchis

il/elle fléchit

nous fléchissons

vous fléchissez

ils/elles fléchissent

Ce programme a la même structure générale queflex-nom-mf.pl. Il permet de flé-chir les verbes des premier et deuxième groupes. Il prend en entrée un radical verbalet le groupe du verbe (1 pour le premier groupe et2 pour le deuxième).

La principale différence entreflex-verb.plet flex-nom-mf.plest qu’il y a plus depronoms personnels sujets et de marques de flexion verbale4 que de déterminants in-définis et de marques du pluriel. Ce nombre justifie l’utilisation de tableaux permet-tant de stocker et d’utiliser ces données d’une manière systématique. Le programmecontient ainsi un tableau pour les pronoms personnels sujets (@pronom), un deuxièmepour les flexions des verbes du premier groupe (@groupe1 ) et un troisième pourcelles du deuxième groupe (@groupe2 ). Ces variables étant de types tableaux, leursnoms commencent par le caractère@, alors que les variables scalaires sont identifiéespar le caractère$. Elles doivent être déclarées parmy comme les variables scalaires,lors de leur première utilisation.

Le radical du verbe étant entré dans la variable$radical , son groupe dans$groupe , la partie centrale du programme va permettre la construction de l’infinitif($infinitif ) et la sélection des flexions à utiliser. Ces deux opérationsrépondentà la même logique :

– si le verbe à fléchir est du premier groupe, on obtient l’infinitif en ajoutant ladésinenceer au radical, et on utilisera les marques du tableau@groupe1 ;

– si le verbe à fléchir est du deuxième groupe, on obtient l’infinitif en ajoutant ladésinenceir au radical, et on utilisera les marques du tableau@groupe2 ;

– si l’utilisateur n’a pas correctement indiqué un de ces deux groupes, le pro-gramme doit se terminer.

Ces différentes possibilités sont orchestrées par une structure conditionnelle enif ... elsif ... elsecomme présenté en section 3.5. La comparaison qui permet de

4. Nous utilisons ici le terme de « marque flexionnelle » pour les désinences. Le terme de « suf-fixe » est réservé aux seuls affixes constructionnels.

Page 126: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

134 Perl pour les linguistes

connaître le groupe du verbe utilise l’opérateur d’égaliténumérique== dans les condi-tionnelles (lignes 18 et 22). Cet opérateur est l’équivalent de eq pour les nombrescomme indiqué au paragraphe 3.5.2.1.

Le programme utilise une quatrième variable de type tableau@flexion qui re-çoit une copie de@groupe1 ou de@groupe2 selon que le verbe est du premierou du deuxième groupe (lignes 20 et 24 du listing 3.6). Cette variable est déclarée(ligne 16) en dehors du bloc conditionnel pour garantir sa visibilité dans l’ensembledu programme. Un tableau déclaré sans être immédiatement affecté estvide, autre-ment dit il ne possède aucun élément. Lors de l’affectation (ligne 20 ou 24), c’estl’ensemble des éléments du tableau copié qui est affecté dans@flexion .

La dernière partie du programme affiche le résultat. Ce dernier comprend unephrase introductrice (lignes 30 et 31) dans laquelle l’infinitif est affiché. Sont ensuiteaffichées les 6 lignes correspondant aux différentes flexions du verbe. Pour chacuned’elle le programme affiche à la suite :

– le pronom correspondant (stocké dans le tableau@pronom) ;

– le radical du verbe ($radical ) ;

– la désinence correspondante (stockée dans le tableau@flexion ).

Comme le pronom et la désinence sont stockés dans des tableaux, il est nécessaired’accéder au valeurs contenues dans les cellules de ceux-ci. L’accès à ces valeurs sefait par l’expression$flexion[ n] composée du nom du tableauflexion et del’indice n de l’élément souhaité. Comme la valeur ainsi obtenue est un scalaire, sonidentifiant commence par$ ; on n’utilise le symbole@dans une expression que lorsquecelle-ci correspond à un tableau. Les 6 dernières instructions sont donc pratiquementidentiques : seul change le numéro de l’indice dans les deux tableaux. La ligne cor-respondant à la première personne utilise donc l’indice0. $pronom[0] est la chaîneje, et$flexion[0] est soiter soit ir en fonction du groupe du verbe.

REMARQUE.– La notation ci-dessus pour les éléments d’un tableau peutêtre utiliséepour modifier ou ajouter des éléments. Ainsi, on aurait pu stocker les pronoms dans letableau@pronomen remplaçant la ligne 4 par la suite d’affectations suivante :$pronom[0] = "je";

$pronom[1] = "tu";

etc.

REMARQUE.– L’usage d’un tableau pour stocker les différentes valeurs des pronomset des désinences n’est pas nécessaire pour ce programme. Toutefois, comme nous leverrons par la suite dans une autre version de ce même programme, l’utilisation d’untableau permet de condenser grandement cette dernière phase d’affichage.

Page 127: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Les bases de Perl 135

3.6.2. Hachages

Dans un tableau, l’accès aux éléments se fait en utilisant leurs numéros. Les ha-chages (outableaux associatifs, ou encorehashes) sont des structures de données trèsproches des tableaux mais pour lesquelles l’accès aux éléments se faitvia une chaînede caractères quelconque, appeléeclé. On peut par exemple utiliser un hachage pourcréer une liste de formes plurielles défectives, dont l’accès se feraitvia leur forme ausingulier. Un tel hachage s’exprime de la façon suivante, enindiquant les couples (clé,valeur) par une flèche (=>) et en séparant les couples par des virgules :

( "ail" => "aulx", "ciel" => "cieux", "oeil" => "yeux" )

En reprenant le schéma précédemment utilisé pour le tableaude pronoms personnelssujets, ce hachage de pluriels défectifs pourrait être représenté comme suit :

oeil => yeuxail => aulxciel => cieux

La deuxième colonne du schéma donne les valeurs stockées et la première les clésqui permettent d’y accéder. Contrairement aux listes, l’ordre dans lequel ces valeurssont stockées n’est pas significatif.

Le hachage des pluriels défectifs peut être utilisé pour améliorer le programmeflex-nom-masc2.plafin qu’il traite correctement ces trois noms. C’est ce qui est faitdansflex-nom-irreg.plprésenté en listing 3.7.

Listing 3.7 – flex-nom-irreg.plExemple d’utilisation des hachages : le traitement des pluriels défectifs

1 use strict;2 use locale;3

4 my %defectif = ("ail" => "aulx", "ciel" => "cieux",5 "oeil" => "yeux");6

7 print "Entrer un nom commun masculin singulier : ";8 my $nom = <STDIN>;9 chomp $nom;

10

11 my $pluriel;12 if ( defined( $defectif$nom ) )

Page 128: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

136 Perl pour les linguistes

13 $pluriel = $defectif$nom;14 15 else 16 $pluriel = $nom . "s";17 18

19 print "Les flexions de \"", $nom, "\" sont :\nun ", $nom,20 "\ndes ", $pluriel, "\n\n";

Ligne de commande :perl flex-nom-irreg.pl

Exemples de déroulement :(les chaînes tapées par l’utilisateur sont en gras)Entrer un nom commun masculin singulier : ciel

Les flexions de "ciel" sont :

un ciel

des cieux

Entrer un nom commun masculin singulier : lapin

Les flexions de "lapin" sont :

un lapin

des lapins

Dans ce programme le hachage qui stocke les pluriels défectifs est affecté à la va-riable%defectif (ligne 4). Comme toutes les variables de type hachage, son nomcommence par le caractère%. Le hachage est ensuite utilisé dans une conditionnellepour déterminer si le nom entré par l’utilisateur est connu par le programme commeayant un pluriel défectif ou bien s’il doit être considéré comme un nom à pluriel régu-lier (ligne 12). Dans le premier cas, la forme au pluriel seracelle qui est stockée dansle hachage (ligne 13). Dans le second, elle est calculée en concaténant unsà la formeau singulier (ligne 16).

L’accès à une valeur conservée dans le hachage%defectif se fait au moyend’une expression composée du nom du hachage, en l’occurrence defectif , suivide la clé correspondante entre accolades. Cette valeur étant un scalaire, l’identifi-cateur du hachage est donc précédé par$. Par exemple, la valeur associée à la clé"ciel" est représentée par$defectif"ciel" . Plus généralement, si$nomcontient l’une des clés du hachage%defectif , la valeur qui lui est associée sera$defectif$nom .

Pour savoir si le nom à traiter est présent dans le hachage, ilfaut en fait vérifiers’il a été défini comme clé, c’est-à-dire si une valeur lui a été associée. Dans le cascontraire, l’interpréteur lui associe une valeurindéfinie. On utilise pour ce faire la

Page 129: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Les bases de Perl 137

fonction prédéfiniedefined qui permet précisément de savoir si une valeur a été as-sociée à une clé donnée ou pas. L’expressiondefined( $defectif$nom )est une expression booléenne (sa valeur est VRAI ou FAUX), etest utilisée commecondition dans une structure conditionnelle. Si elle vaut VRAI, le verbe est défectif, etson pluriel est justement la valeur associée ; si elle vaut FAUX, le pluriel est régulier.

REMARQUE.– La notation permettant d’accéder à la valeur associée à une clé dans unhachage ($hachage clé ) permet également de modifier la valeur en utilisant uneaffectation :$hachage clé = valeur ; .

De plus, dans le cas où la clé n’était pas définie, cette opération a comme résultatl’insertion d’un nouveau couple (clé, valeur) dans le hachage. On peut ainsi remplacerles lignes 4 et 5 par les affectations suivantes :$defectif"ail" = "aulx";

$defectif"ciel" = "cieux";

$defectif"oeil" = "yeux";

3.7. Structures de contrôle : boucles

Le deuxième type de structures de contrôle fondamental des langages de program-mation impératifs comme Perl sont les boucles. Une boucle est une instruction com-plexe qui permet de répéter un ensemble d’instructions sansavoir à réécrire plusieursfois le code correspondant. En reprenant l’exemple du programmeflex-verb.pl, onpeut voir que 6 instructions quasi identiques sont utilisées pour afficher les 6 formesconjuguées du verbe. L’utilisation d’une boucle aurait permis dans ce cas de n’écrirequ’une seule fois l’instruction d’affichage des formes fléchies, en indiquant seulementles modifications à effectuer d’une ligne à l’autre (c’est-à-dire changer le numéro decellule des tableaux). Il existe plusieurs sortes de boucles. Les principales sont : lesboucleswhile contrôlées par une condition booléenne ; les bouclesfor indexées surles éléments d’une série généralement numérique ; les bouclesforeach indexées surles éléments d’une liste (c’est-à-dire d’un tableau parcouru séquentiellement).

3.7.1. Boucleswhile

On utilise habituellement des boucleswhile lorsqu’on ne connaît pas à l’avance lenombre d’itérations qu’il faut effectuer. C’est en particulier le cas lorsque l’on traitedes données dont on ne connaît pas la quantité, par exemple sil’on souhaite fléchirnon pas un mais une série (de longueur quelconque) de noms masculins.

3.7.1.1.Traitement de données saisies par l’utilisateur

Nous verrons dans un premier cas comment répéter un traitement interactif, c’est-à-dire avec un utilisateur qui entre les données au fur et à mesure, puis un traitementqui se base sur des données contenues dans un fichier.

Page 130: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

138 Perl pour les linguistes

Ce traitement est réalisé par le programmeflex-liste-noms-masc1.plprésenté enlisting 3.8 et qui reprend pour l’essentielflex-nom-masc2.pl. Le traitement proposépour un nom masculin singulier est répété pour autant de nomsque l’utilisateur veutbien fournir au programme.

Listing 3.8 – flex-liste-noms-masc1.plExemple d’utilisation des boucleswhile : la flexion d’une liste de noms masculinssaisis par l’utilisateur

1 use strict;2 use locale;3

4 print "Entrez un nom masculin singulier (ou X pour finir) : ";5 my $nom = <STDIN>;6 chomp $nom;7

8 while ( $nom ne "X" ) 9 my $pluriel = $nom . "s";

10 print "Les flexions de \"", $nom, "\" sont :\nun ", $nom,11 "\ndes ",$pluriel, "\n\n";12 print "Entrez un nouveau nom (ou X pour finir): ";13 $nom = <STDIN>;14 chomp $nom;15 16

17 print "Fin du programme !\n";

Ligne de commande :perl flex-liste-noms-masc1.pl

Exemple de déroulement :Entrez un nom masculin singulier (ou X pour finir) : lapin

Les flexions de "lapin" sont :

un lapin

des lapins

Entrez un nouveau nom (ou X pour finir) : boeuf

Les flexions de "boeuf" sont :

un boeuf

des boeufs

Entrez un nouveau nom (ou X pour finir) : X

Fin du programme !

Le traitement réalisé parflex-liste-noms-masc1.plest strictement identique à celuide flex-nom-masc2.pl, mais les opérations de lecture, traitement et affichage y sontmises en boucle.

Page 131: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Les bases de Perl 139

Comme on le voit à l’exécution, une fois le traitement du premier nom terminé, leprogramme relance l’utilisateur par une nouvelle invite, traite le nom entré, et ainsi desuite. L’utilisateur met fin au programme en tapant, comme valeur d’entrée, la chaîneX.

Plus formellement, le programmeflex-liste-noms-masc1.plfonctionne de la ma-nière suivante :

1) il lit la première chaîne donnée par l’utilisateur en entrée et supprime son ca-ractère de fin de ligne (lignes 5 et 6) ;

2) si cette chaîne n’est pasX (ligne 8) :a) la chaîne est traitée comme dans le programme 3.7flex-nom-masc.pl(lignes

9 à 11) ;b) il invite l’utilisateur à entrer un nouveau nom et lit la valeur donnée en entrée

(lignes 12 à 14) ;c) il réitère le traitement à partir de l’étape 2 ;

3) si la chaîne entrée estX, le programme affiche un message final avant de s’arrê-ter (ligne 17).

Le code du programmeflex-liste-noms-masc1.plrajoute essentiellement à celui deflex-nom-masc.plune bouclewhile.

Une instructionwhile comprend deux parties : un bloc d’instructions itéré et uneexpression booléenne (condition) qui permet d’en contrôler l’itération. Tant que cetteexpression à une valeur VRAI, le bloc d’instructions est à nouveau exécuté en entier.

La condition qui contrôle la bouclewhile en ligne 8 est un test portant sur lecontenu de la variable$nom. Si l’utilisateur a entré la chaîneX alors l’expressionbooléenne$nom ne "X" vaut FAUX (ne est l’opérateur de différence) : le corps dela boucle n’est pas exécuté et le programme passe à l’instruction de la ligne 17 avantde s’arrêter.

Si l’utilisateur entre une chaîne autre queX, l’expression booléenne vaut VRAIet le corps de la bouclewhile va être exécuté. Les instructions de traitement et d’affi-chage habituelles vont être exécutées (lignes 9 à 11). Puis,un nouveau message va êtreaffiché pour inviter l’utilisateur à entrer un nouveau nom, qui sera lu et stocké dansla variable$nom. La nouvelle valeur varemplacerla valeur précédemment stockéedans cette variable. La bouclewhile est ensuite exécutée à nouveau, c’est-à-dire quela condition de la ligne 8 va être recalculée avec la nouvellevaleur de$nom. Si ellevaut VRAI, le corps de la boucle est exécuté. Sinon, il ne l’est pas et le programmes’arrête.

Une fois la boucle terminée, les instructions situées aprèsl’accolade fermante dela ligne 15 sont exécutées, un simple message de fin de programme sera affiché dansnotre cas.

Page 132: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

140 Perl pour les linguistes

3.7.1.2.Traitement de données contenues dans un fichier

La grande majorité des programmes conçus pour traiter des données en nombre nes’attendent pas à ce qu’un utilisateur les saisisse au clavier au fur et à mesure. Le moded’utilisation principal de ces programmes est de leur communiquer lors de leur lan-cement unfichier de texte contenant l’ensemble des données à traiter. Le programmeeffectue alors son traitement sans intervention de l’utilisateur.

Le fonctionnement d’un tel programme reste très proche de celui de flex-liste-noms-masc1.pl: à l’aide d’une bouclewhile il va répéter les opérationslecture, trai-tement, affichage. Les chaînes lues seront par contre contenues dans les lignes du fi-chier de données : une ligne de texte correspond à ce que saisit un utilisateur au clavierquand il appuie sur la toucheEntréedu clavier. Les lignes d’un fichier sont lues defaçon séquentielle : à chaque opération de lecture c’est le contenu de la ligne suivantequi est utilisé, jusqu’à ce que le fichier ait été entièrementlu, c’est-à-dire jusqu’à cequ’il n’y ait plus de nouvelle ligne à lire dans le fichier (on parle dans ce cas defin defichier).

Le programmeflex-liste-noms-masc2.pl(listing 3.9) est ainsi capable de fléchir unnombre quelconque de noms au masculin singulier contenus dans un fichier de texte,un mot par ligne, et d’écrire le résultat de son traitement.

Listing 3.9 – flex-liste-noms-masc2.plExemple d’utilisation des boucleswhile : flexions d’une liste de noms contenue dansun fichier

1 use strict;2 use locale;3

4 while ( my $nom = <STDIN> ) 5 chomp $nom;6 my $pluriel = $nom . "s";7 print $pluriel, "\n";8

Ligne de commande :perl flex-liste-noms-masc2.pl < fichier d’entrée

Exemple de déroulement :Comme ce programme nécessite un fichier de don-nées, nous utiliserons le fichierliste-animaux.txt dont le contenu est le sui-vant :âne

boeuf

chat

Page 133: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Les bases de Perl 141

cheval

chien

La commande :perl flex-liste-noms-masc2.pl < liste-animaux.txt

donne comme résultat affiché dans le terminal :ânes

boeufs

chats

chevals

chiens

Ce type d’utilisation correspond à la notion de redirectiondu flux d’entrée, commedécrit au paragraphe 2.6.2, page 98.

Ce programme fonctionne sur le même principe queflex-liste-noms-masc1.pl. Lapremière différence est l’absence de tout élément de dialogue avec l’utilisateur (plusd’invite ni de phrase explicitant les résultats).

La seconde différence est que l’opération de lecture est maintenant directementréalisée dans la condition duwhile. Cette syntaxe condensée ne correspond par aupremier abord à celle d’une condition et n’est donc pas censée se trouver à cet endroitdans une bouclewhile. L’explication en est la suivante.

A chaque passage dans la boucle, la valeur de la condition doit être calculée poursavoir si la boucle continue ou s’arrête. Si la condition esten fait une instruction,celle-ci est exécutée : dans ce cas, un nom est lu en entrée. Pour obtenir la valeur devérité, Perl utilise le résultat de l’instruction : si celle-ci a pu être réalisée, la valeur decondition est VRAI ; si l’instruction n’a pas pu se dérouler,la valeur est FAUX.

Plus précisément dans le cas deflex-liste-noms-masc2.pl, l’opération de lecture($nom = <STDIN>) sera évaluée comme FAUX s’il n’y a pas de données à lire,autrement dit, si plus aucun nom n’est disponible dans le fichier. Dans ce cas, le pro-gramme s’arrête. Si un nom a pu être lu, il est traité, et la boucle se répète.

La séquence suivante correspond au fonctionnement de la commande :perl flex-liste-noms-masc2.pl < liste-animaux.txt

– arrivée dans la bouclewhile : exécution de l’expression$nom = <STDIN>.La première ligne du fichier est lue et son contenu (ânesuivi d’une fin de ligne) eststocké dans$nom;

– comme la lecture a pu être effectuée, la condition vaut VRAIet le corps de laboucle est exécuté : le programme afficheânesen sortie ;

Page 134: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

142 Perl pour les linguistes

– retour dans la bouclewhile, et à nouveau exécution de l’expression$nom = <STDIN>. Cette fois c’est la ligne suivante du fichier qui est lue,$nomreçoit alors la valeurboeuf suivie d’une fin de ligne. La condition vaut à nouveauVRAI, et boeufsest affiché ;

– ainsi de suite jusqu’à l’affichage dechiensaprès lecture de la dernière ligne dufichier ;

– retour dans la bouclewhile, et à nouveau exécution de l’expression$nom = <STDIN>. Cette opération ne peut être exécutée puisqu’il n’y a pas deligne après celle qui contenaitchien. La condition est alors évaluée à FAUX. Le corpsde la bouclewhile n’est pas exécuté et le programme se termine.

3.7.1.3.Notes sur les boucles de lecture

La très grande majorité des programmes de traitement de données en Perl ont unestructure identique à celle deflex-liste-noms-masc2.pl: après d’éventuelles initialisa-tions, les données d’entrée sont lues une à une sur le flux d’entrée standard (STDIN).Un calcul est effectué pour chacune d’elles et son résultat est écrit sur le flux de sortiestandard (STDOUT).

Le squelette suivant est donc la charpente la plus courante d’un programme Perl :

while ( my $ligne = <STDIN> )

...

L’utilisation d’un programme de ce type est souvent conçue pour être appliquéeà des données contenues dans un fichier, indiqué dans la lignede commande par uneredirection suivant le modèle :

perl programme.pl < fichier

Toutefois, il est toujours possible d’utiliser ces programmes de façon interactive,en entrant les données au clavier :

perl programme.pl

Il est également possible de placer le programme dans une séquence de traitements,en utilisant la notion depipe:

commandeX | perl programme.pl

Pour plus de détails sur la gestion des flux, voir le chapitre 2.

Page 135: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Les bases de Perl 143

3.7.2. Bouclesfor

Les bouclesfor sont principalement utilisées lorsque l’itération de la boucle estindexée sur un compteur numérique. C’est par exemple le cas lorsqu’on souhaite trai-ter séquentiellement, dans l’ordre des indices, les éléments d’un tableau. L’utilisationd’une bouclefor serait par exemple totalement appropriée pour réaliser l’affichagedes résultats dans le programmeflex-verb.pl. Le listing 3.10 présente une version dece programme plus conforme à l’usage.

Listing 3.10 – flex-verb2.plExemple d’utilisation des boucles : flexion d’un verbe

1 use strict;2 use locale;3

4 my @pronom = ("je", "tu", "il/elle", "nous", "vous", "ils/e lles");5 my @groupe1 = ("e", "es", "e", "ons", "ez", "ent");6 my @groupe2 = ("is", "is", "it", "issons", "issez", "issent ");7

8 print "Entrez le radical d’un verbe du 1er ou du 2e groupe : ";9 my $radical = <STDIN>;

10 chomp $radical;11

12 print "Quel est le groupe du verbe (1/2) ? ";13 my $groupe = <STDIN>;14 chomp $groupe;15

16 my @flexion;17 my $infinitif;18 if ($groupe == 1) 19 $infinitif = $radical . "er";20 @flexion = @groupe1;21 22 elsif ($groupe == 2) 23 $infinitif = $radical . "ir";24 @flexion = @groupe2;25 26 else 27 die "Ce programme ne traite que les 1er et 2e groupes.\n";28 29

30 print "Les formes du verbe \"", $infinitif,31 "\" au présent de l’indicatif sont :\n";32 for ( my $i = 0 ; $i <= 5 ; $i++ ) 33 print $pronom[$i], " ", $radical, $flexion[$i], "\n";34

Ligne de commande :perl flex-verb2.pl

Exemple de déroulement :voir paragraphe 3.6.1.

Page 136: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

144 Perl pour les linguistes

Ce programme fonctionne d’une façon strictement identiqueà flex-verb.pl. Laseule différence est que les six instructionsprint des lignes 33 à 38 du listing 3.6sont remplacées par une bouclefor dont le corps est réduit à une unique instructionprint . Cette boucle utilise un compteur numérique$i qui est initialisé à 0 et ensuiteincrémenté de 1 à chaque itération jusqu’à atteindre 5. L’initialisation est réalisée parla première partie de l’expression introduite par le mot-cléfor : $i = 0 . L’incrémen-tation l’est par la troisième partie :$i++ au moyen de l’opérateur++ qui incrémentede 1 la variable qui lui est fournie comme argument. En d’autres termes,$i++ eststrictement équivalent à$i = $i + 1 . La condition de contrôle proprement ditede la boucle est l’expression booléenne$i <= 5 qui indique que la boucle doit êtreitérée tant que la valeur de$i est inférieure ou égale à 5.

Plus précisément, l’exécution d’une bouclefor se déroule de la manière suivante :

1) l’instruction d’initialisation qui se trouve dans la première partie de l’expressionqui suit le mot-cléfor est exécutée avant la première itération.$i reçoit ainsi la valeur0 ;

2) la condition$i <= 5 qui se trouve en deuxième place dans l’expression estensuite évaluée ;

3) si elle vaut VRAI :a) le corps de la boucle est exécuté. On imprime le pronom et laforme fléchie

du verbe pour la valeur courante du compteur$i ;b) l’instruction d’incrémentation qui forme la troisième partie de l’expression

qui suit lefor est exécutée.$i est incrémenté de 1 ;c) on recommence l’itération à partir de l’étape (2) ;

4) si elle vaut FAUX (donc si$i a atteint la valeur 6), l’exécution dufor estterminée et le programme passe aux instructions qui suiventle corps de la boucle.Dans le cas deflex-verb2.pl, la bouclefor étant la dernière instruction du programme,ce dernier s’arrête.

Au final, la bouclefor peut être remplacée par les instructions suivantes, basée surune bouclewhile, qui lui sont totalement équivalentes :my $i = 0;

while ( $i <= 5 )

print $pronom[$i], " ", $radical, $flexion[$i], "\n";

$i++;

On peut ainsi voir qu’une bouclefor n’est en fait qu’une version compacte d’uneboucle while. Les trois paramètres qui sont communiqués se retrouvent dans les ins-tructions ci-dessus :

– l’initialisation de l’index (my $i = 0; ) avant le début de la bouclewhile ;

– la condition ($i <= 5 ) comme condition duwhile ;

Page 137: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Les bases de Perl 145

– l’incrémentation de l’index ($i++; ) comme dernière instruction du corps de laboucle.

REMARQUE.– Dans le cas du programmeflex-verb2.pl, la bouclefor sert à parcourirun tableau (ou plutôt deux tableaux de taille identique). Dans de nombreux cas, commeon le verra par la suite, le parcours se fait sans que l’on sache à l’avance la taille dutableau (ici 6 cellules). Il est en fait possible d’accéder directement au numéro dudernier élément d’un tableau@t en utilisant la notation :$#t . Ainsi, il est tout à faitpossible dansflex-verb2.plde remplacer la valeur5 par$#pronom .

3.7.3. Bouclesforeach

Les bouclesforeach sont très proches des bouclesfor . Elles utilisent comme cesdernières une variable pour parcourir un ensemble de valeurs pour chacune desquellesle corps de la boucle est exécuté. Mais dans le cas des bouclesforeach, cet index n’estpas un compteur. C’est une variable qui prend successivement les valeurs desélémentsd’une liste (c’est-à-dire d’un tableau). On peut par exemple utiliser une boucleforeachà la place d’une bouclefor pour afficher les formes fléchies d’un verbe. Le programmeflex-verb3.plest ainsi une variante deflex-verb2.plqui met en œuvre cette méthode.

Listing 3.11 – flex-verb3.plExemple d’utilisation des bouclesforeach : flexion d’un verbe

1 use strict;2 use locale;3

4 my @pronom = ( "je", "tu", "il", "elle", "nous", "vous",5 "ils", "elles" );6 my %groupe1 = ( "je" => "e", "tu" => "es", "il" => "e",7 "elle" => "e", "nous" => "ons", "vous" => "ez",8 "ils" => "ent", "elles" => "ent" );9 my %groupe2 = ( "je" => "is", "tu" => "is", "il" => "it",

10 "elle" => "it", "nous" => "issons",11 "vous" => "issez", "ils" => "issent",12 "elles" => "issent" );13

14 print "Entrez le radical d’un verbe du 1er ou du 2e groupe : ";15 my $radical = <STDIN>;16 chomp $radical;17

18 print "Quel est le groupe du verbe (1/2) ? ";19 my $groupe = <STDIN>;20 chomp $groupe;21

22 my %flexion;23 my $infinitif;24 if ( $groupe == 1 ) 25 $infinitif = $radical . "er";26 %flexion = %groupe1;27

Page 138: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

146 Perl pour les linguistes

28 elsif ( $groupe == 2 ) 29 $infinitif = $radical . "ir";30 %flexion = %groupe2;31 32 else 33 die "Ce programme ne traite que les 1er et 2e groupes.\n";34 35

36 print "Les formes du verbe \"", $infinitif,37 "\" au présent de l’indicatif sont :\n";38

39 foreach my $pro ( @pronom )40 print $pro, " ", $radical, $flexion$pro, "\n";41

Ligne de commande :perl flex-verb3.pl

Exemple de déroulement :voir paragraphe 3.6.1.

Ce programme présente trois différences avecflex-verb2.pl:

1) le tableau@pronomcontient maintenant 8 éléments, puisqu’on y a ajouté lespronoms féminins de troisième personne ;

2) les marques flexionnelles des verbes sont représentées aumoyen de hachagesdont les clés sont les pronoms personnels sujets (lignes 6 à 12 du listing 3.11) et lesvaleurs les désinences. Lors de la sélection du groupe du verbe, c’est donc un de cesdeux hachages (%groupe1 ou%groupe2 ) qui sera recopié dans%flexion (ligne26 ou 30). Le hachage%flexion doit donc être préalablement déclaré (ligne 22)en dehors du bloc conditionnel. A partir de ce hachage, pour connaître la désinence,il suffit d’indiquer que l’on souhaite avoir accès à la valeurassociée à un pronompersonnel. Ainsi, la désinence pour la première personne dusingulier est obtenue par$flexion"je" ;

3) l’indice $i sur lequel reposait la bouclefor deflex-verb2.plest remplacé par lavariable$pro . Lors de la première itération,$pro reçoit la première valeur de la listepronom (c’est-à-dire"je" ), lors de la deuxième itération, elle reçoit la deuxièmevaleur (c’est-à-dire"tu" ), et ainsi de suite jusqu’à ce que la fin de la liste soit atteinte.Pour chaque pronom, une ligne est affichée avec le pronom stocké dans$pro , leradical du verbe et la valeur associée à ce pronom dans le hachage%flexion (ligne40).

Une boucleforeachs’utilise avec la syntaxe suivante :

foreach variable ( liste ) ...

et entraîne une exécution du corps de la boucle pour chaque élément deliste , lavaleur de cet élément étant à chaque fois stockée dansvariable .

Page 139: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Les bases de Perl 147

La boucleforeachdeflex-verb3.plest totalement équivalente à la bouclefor sui-vante :for ( my $i = 0 ; $i <= $#pronom ; $i++)

my $pro = $pronom[$i];

print $pro, " ", $radical, $flexion$pro, "\n";

Les bouclesforeachont donc une syntaxe de mise en place plus concise que celledes bouclesfor . De ce fait, elles sont utilisées plus couramment pour les parcours detableaux, tant que la position des éléments de ces tableaux n’est pas utile.

3.8. Manipulation de fichiers

S’il est possible d’indiquer à un programme qu’il doit exploiter ou produire desdonnées stockées dans un fichier en utilisant les flux standards et les redirections, ilest également possible de manipuler explicitement des fichiers depuis un programme.Ceci est nécessaire, notamment, lorsque plusieurs sourcesde données sont utiliséspar un même programme. Les étapes principales de l’utilisation d’un fichier sont lessuivantes :

– ouverture : il s’agit de la première opération à réaliser, elle exprime que lecontenu du fichier en question va être utilisé par la suite. C’est également à ce stadeque le type d’utilisation du fichier est indiqué (lecture ou écriture) ;

– lecture ou écriture : cette opération est très similaire à celle de la lecture ou del’écriture sur les flux standard, mais s’applique à un descripteur de fichier préalable-ment ouvert ;

– fermeture : une fois les données lues, il est nécessaire de fermer le fichier, c’est-à-dire d’indiquer au système d’exploitation que le fichier ne sera plus utilisée par leprogramme (et est donc à nouveau disponible pour d’autres utilisations).

Un fichier est identifié, au niveau du système d’exploitation, par un nom et un em-placement (ou adresse) dans le système de fichiers. Toute opération de manipulationde fichier entraîne un dialogue entre le programme Perl et le système d’exploitation.Dans un programme Perl, un fichier sera identifié par une variable spécifique, appeléedescripteur de fichier. Une variable de ce type n’a pas besoin d’être déclarée, elleestemployée pour identifier le fichier correspondant lors de chacune des étapes de sonutilisation.

La distinction dans l’utilisation d’un fichier étant son mode d’utilisation (lectureou écriture), le détail de chacun d’eux est présenté dans ce qui suit.

Page 140: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

148 Perl pour les linguistes

3.8.1. Lecture d’un fichier texte

Un fichier utilisé en lecture s’utilise de la même façon que leflux d’entrée standard(STDIN). Toutefois, il faut au préalable qu’il soitidentifiépar le programme, et qu’ilsoit ouvert.

L’identification se base sur son adresse dans la hiérarchie de fichiers gérée parle système d’exploitation. Elle consiste principalement en son nom et, si besoin, lechemin permettant d’y accéder s’il ne se trouve pas dans le répertoire courant. Lesdétails des notations des chemins sont présentés au chapitre 2.

Le programmeflex-nom-invar-fichier.pl(listing 3.12) effectue la flexion au plurield’un nom commun en utilisant une liste de noms invariables stockés dans le fichiernoms-invariables.txt. Ce fichier est au format texte, et contient simplement un nominvariable par ligne. Le programme effectue la flexion de la même façon que dansflex-nom-invar.pl, en ajoutant uns aux noms qui ne sont pas invariables. L’intérêt d’utiliserun fichier pour stocker ces noms invariables est double. Toutd’abord, comme il existeplusieurs centaines de noms de ce type, leur stockage dans lecode du programme estfastidieux. Ensuite, cette liste est susceptible d’être modifiée, et dans ce cas il est plussimple de modifier la liste que le (ou les) programme(s) qui l’utilise(nt).

Voici les premières lignes du fichiernoms-invariables.txt(cette liste a été obtenueà partir du lexique Morphalou) :

abadis

abas

abatis

abattis

abax

abbevillois

abcès

abdalas

abies

abras

abrasax

abraxas

abroutis

abscons

abus

Le programmeflex-nom-invar-fichier.plutilise donc deux sources de données :

– les noms invariables qui sont stockés dans le fichiernoms-invariables.txt;

– le nom à fléchir qui est lu dans l’entrée standard de façon classique.

Page 141: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Les bases de Perl 149

Listing 3.12 – flex-nom-invar-fichier.plExemple d’utilisation d’un fichier en lecture : flexion des noms avec prise en compted’une liste de noms invariables

1 use strict;2 use locale;3

4 my %invariable;5

6 open ( INVAR, "<", "noms-invariables.txt");7 while ( my $ligne = <INVAR> ) 8 chomp $ligne;9 $invariable$ligne = 1;

10 11 close (INVAR);12

13 print "Entrez un nom commun singulier : ";14 my $nom = <STDIN>;15 chomp $nom;16

17 my $pluriel;18 if ( defined ( $invariable$nom ) ) 19 $pluriel = $nom;20 21 else 22 $pluriel = $nom . "s";23 24

25 print "Le pluriel de \"", $nom, "\" est : \"", $pluriel, "\"\n ";

Ligne de commande :perl flex-nom-invar-fichier.pl

Exemple de déroulement :(les chaînes tapées par l’utilisateur sont en gras)Entrez un nom commun singulier : lynxLe pluriel de "lynx" est : "lynx"

Ce programme se déroule en trois phases :

– une première phase de lecture du fichier et de stockage des données contenues(autrement dit, de la liste des noms invariables) ;

– une phase de lecture du nom à fléchir en utilisant le flux d’entrée standard ;

– une phase de calcul de la forme fléchie en se basant sur la liste de noms inva-riables, puis d’affichage du résultat obtenu.

Le hachage%invariable sert de structure de données pour stocker la liste desnoms invariables. Chacun de ces noms va en effet être considéré comme une clé, etse voir associer la valeur arbitraire1. Dès lors, il suffit, pour savoir si un nom estinvariable, de vérifier si sa valeur est définie dans le hachage, comme dansflex-nom-irreg.pl (listing 3.7).

Page 142: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

150 Perl pour les linguistes

Le remplissage de ce hachage se fait à partir des noms stockésdans le fichiernoms-invariables.txt. Les instructions permettant l’exploitation de ce fichier sont :

– son ouverture par le biais de la fonctionopen (ligne 6). La manipulation de cefichier utilise le descripteurINVAR : le nom est arbitraire, et est exprimé en majusculescomme il est d’usage en Perl. La fonctionopenprend trois arguments : le descripteur,le caractère< indiquant que le fichier est ouvert enlecture, et le nom du fichier dansla hiérarchie de fichiers ;

– une lecture complète du fichier, ligne par ligne (lignes 7 à 10). La syntaxe decette opération est identique à celle vue au paragraphe 3.7.1.3, en utilisant toutefois ledescripteurINVAR en lieu et place du flux d’entrée standard (STDIN) ;

– la fermeture du fichier une fois celui-ci lu en intégralité (ligne 11). Ceci se faitvia la fonctionclosedont le seul paramètre est le descripteur du fichier.

REMARQUE.– Tout programme qui utilise un fichier externe contenant des données estdépendant de celui-ci. Notamment, si ce fichier est absent, mal placé ou indisponible,le traitement ne peut s’effectuer correctement. Cette situation courante nécessite deprendre une précaution supplémentaire lors de l’ouvertured’un fichier. En effet, ilconvient de vérifier que cette opération s’est bien passée avant de passer à la suite dutraitement, et notamment à l’exploitation du contenu du fichier.

Pour cela, la phase d’ouverture d’un fichier est généralement réalisée par l’ins-truction suivante :

open ( DESCRIPTEUR, "<", nom_du_fichier ) or die

"Impossible d’ouvrir le fichier : ", $!, "\n"

Cette syntaxe particulière, basée sur le connecteur logique or indique qu’en casd’échec de l’ouverture, l’instruction située après leor doit être exécutée. Dans le casoù l’ouverture du fichier a pu être réalisée, la seconde instruction est ignorée.

Dans le cas où la fonctionopenn’a pu s’exécuter correctement, le programme vadonc s’arrêter du fait de l’instructiondie. Ce faisant, un message d’erreur va être af-fiché à destination de l’utilisateur. Ce message est constitué d’un texte indiqué dansle programme (impossible d’ouvrir le fichier) et d’un message d’erreur généré par lesystème d’exploitation et disponible dans la variable spéciale $! 5. Ce message d’er-reur (généralement en anglais) indique la raison pour laquelle l’ouverture du fichier aéchoué. Un message d’erreur typique est :"No such file or directory"ou "Le fichierspécifié est introuvable". Ce message indique donc que le fichier dont le nom est in-diqué à la fonctionopen n’existe pas : parce que son nom est mal orthographié, ou

5. Perl dispose d’un ensemble de variables spéciales, dont lerôle sera présenté au fur et à mesuredans le reste de l’ouvrage. En général, ces variables sont automatiquement affectées par Perl etne sont utilisées que pour afficher ou tester leur contenu.

Page 143: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Les bases de Perl 151

qu’il a été déplacé ou supprimé, etc. L’utilisateur est ainsi prévenu qu’il doit vérifier ladisponibilité de ce fichier, sans quoi le programme ne peut sedérouler correctement.

COMMENTAIRE.– Le cas présenté ici est celui d’une identification simple du fi-chier : seul le nom du fichier est indiqué dans le troisième paramètre de la fonc-tion open. Cette utilisation suppose donc, quand le programme est exécuté, quele fichier en question est dans le répertoire de travail du shell. Si tel n’est pasle cas, le troisième paramètre doit contenir lechemin d’accèsen plus de sonnom, c’est-à-dire une indication du répertoire où il se trouve. La notation dece chemin d’accès varie d’un système d’exploitation à l’autre, alors que le prin-cipe est le même. La principale variation est que sous un système de typeUnix,les différents éléments (répertoires) sont séparés par le symbole / , par exempledans : /home/ident/PPL/03.Bases/noms-invariables.txt . Sous unsystème de la familleWindows, c’est le symbole\ qui joue ce rôle, comme dans :C:\PPL\03.Bases\noms-invariables.txt .

Toutefois, il est possible d’utiliser le symbole/ également sous Windows. Ce sym-bole est notablement plus pratique à utiliser que le précédent, car il n’entre pas enconflit avec le symbole d’échappement\ (qui sert par exemple à exprimer\n et \" ,etc.). Si l’on souhaite utiliser\ , il est alors nécessaire de le doubler. Le fichier précé-dent peut au final s’ouvrir sous Windows avec :

open (INVAR, "<", "C:/PPL/03.Bases/noms-invariables.tx t");

ou bien avec :

open (INVAR, "<", "C:\\PPL\\03.Bases\\noms-invariables .txt");

Il est possible d’utiliser indifféremment des chemins relatifs ou absolus, voir lechapitre 2 pour plus de détails sur les chemins d’accès aux fichiers.

3.8.2. Ecriture dans un fichier texte

Les fichiers peuvent également être utilisés pour stocker les résultats produits parun programme Perl. Dans ce cas, le fichier sera utilisé pour des opérations d’écriture etnon plus de lecture, essentiellement à travers l’instruction print . Avant d’écrire dansun fichier, il est toutefois nécessaire, comme pour la lecture, d’ouvrir celui-ci et de luiassocier un descripteur.

Le programmeflex-verbe-fichier.pleffectue la flexion d’un verbe du premiergroupe au présent et à l’imparfait de l’indicatif, en écrivant les résultats séparémentdans deux fichiers. Les noms de ces fichiers sont calculés par le programme à partirde l’infinitif du verbe.

Page 144: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

152 Perl pour les linguistes

Listing 3.13 – flex-verbe-fichier.plExemple d’utilisation de fichiers en écriture : flexion d’un verbe au présent et à l’im-parfait

1 use strict;2 use locale;3

4 my @pronom = ( "je", "tu", "il/elle", "nous", "vous", "ils/e lles" );

5 my @present = ( "e", "es", "e", "ons", "ez", "ent" );6 my @imparfait = ( "ais", "ais", "ait", "ions", "iez", "aient " );7

8 print "Entrez le radical d’un verbe du 1er groupe : ";9 my $radical = <STDIN>;

10 chomp $radical;11 my $infinitif = $radical . "er";12 my $fic_pre = $infinitif."-present.txt";13 my $fic_imp = $infinitif."-imparfait.txt";14

15 open ( PRESENT, ">", $fic_pre ) or16 die "Impossible d’ouvrir ",$fic_pre, " : ",$!, "\n";17 open ( IMPARFAIT, ">", $fic_imp ) or18 die "Impossible d’ouvrir ", $fic_imp, ": ",$!, "\n";19

20 for ( my $i = 0 ; $i <= 5 ; $i++ ) 21 print PRESENT $pronom[$i], " ", $radical, $present[$i], "\ n";22 print IMPARFAIT $pronom[$i], " ", $radical, $imparfait[$i ], "\n

";23 24

25 print "Les conjugaisons de ", $infinitif,26 " sont disponibles dans les fichiers\n", $fic_pre,27 "\net\n", $fic_imp, "\n";28

29 close ( PRESENT );30 close ( IMPARFAIT );

Ligne de commande :perl flex-verbe-fichier.pl

Exemple de déroulement :(les chaînes saisies par l’utilisateur sont en gras)Entrez le radical d’un verbe du 1er groupe : continu

Les conjugaisons de continuer sont disponibles dans les

fichiers

continuer-present.txt

et

continuer-imparfait.txt

A la suite de ce programme, le fichiercontinuer-present.txtcontient le textesuivant :je continue

tu continues

Page 145: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Les bases de Perl 153

il/elle continue

nous continuons

vous continuez

ils/elles continuent

et le fichiercontinuer-imparfait.txtcontient le texte suivant :je continuais

tu continuais

il/elle continuait

nous continuions

vous continuiez

ils/elles continuaient

REMARQUE.– Les deux fichiers indiqués en résultat sont créés dans le répertoire detravail par l’exécution deflex-verbe-fichier.pl. Si toutefois des fichiers de ce nomexistaient déjà, leur contenu serait remplacé par celui-indiqué ci-dessus. Ce principed’écrasement vaut pour tous les fichiers ouverts en écriture: il convient donc d’êtretrès prudent, car il existe toujours un risque de perdre des données par écrasement.

Détails du programme :

flex-verbe-fichier.plreprend en grande partie le principe de fonctionnementflex-verbe2.pl. Le début du programme consiste en l’initialisation de trois tableaux : unpour les pronoms sujets, et deux pour les désinences du présent (@present ) et del’imparfait (@imparfait ). Le radical du verbe à fléchir est ensuite lu en entrée stan-dard, et l’infinitif en est calculé par ajout deer à la fin du radical.

Les deux fichiers où sont stockés les flexions ont chacun un nomqui dépenddirectement de l’infinitif ainsi calculé (en ajoutant respectivement-present.txtet -imparfait.txt). Les variables$fic_pre et $fic_imp contiennent les noms de fi-chiers ainsi construits.

Les lignes 15 à 18 concernent l’ouverture de ces deux fichiersen écriture. Cetteopération utilise exactement la même syntaxe que pour l’ouverture d’un fichier enlecture. Les paramètres de la fonctionopen sont : le descripteur du fichier (PRESENTou IMPARFAIT), l’indicateur d’une ouverture en écriture (>) et le nom du fichier(fourni ici par une variable).

Les précautions relatives à l’échec possible de l’ouverture du fichier sont lesmêmes que celle prises pour l’ouverture d’un fichier en écriture (en utilisant la syn-taxe « or die »). Les raisons d’un échec sont toutefois généralement différentes(capacité de stockage du support de données atteinte, droits d’accès insuffisants, etc.).

Page 146: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

154 Perl pour les linguistes

La construction des flexions se fait de la même façon que dansflex-verbe2.pl,en concaténant le pronom, le radical et la désinence correspondante, et ce pour lessix personnes. La même bouclefor permet de construire en parallèle les flexions duprésent et de l’imparfait, puisque celles-ci utilisent le même pronom.

Les instructions d’écriture proprement dite (lignes 21 et 22) utilisent la fonctionprint , mais précisent (via le descripteur du fichier placé immédiatement aprèsprint )que la chaîne doit être écrite dans le fichier correspondant.

Les instructionsprint qui ne contiennent pas de descripteur explicite corres-pondent à un affichage en sortie standard, comme c’est le cas en ligne 25. Il estégalement possible d’indiquer explicitement que c’est la sortie standard qui doit êtreutilisée, en utilisant le descripteur STDOUT.

Enfin, les fichiers sont fermés en utilisant la fonctionclose. Cette opération finaliseles fichiers et rend leur contenu disponible pour une utilisation ultérieure.

REMARQUE.– Le contenu d’un fichier en écriture n’est généralement pasvisible tantque le fichier n’est pas fermé. Cette opération de fermeture est donc vitale.

COMMENTAIRES.– Comme l’indique cet exemple, il est donc tout à fait possible pourun programme de manipuler plusieurs flux de données (en entrée et en sortie). Il estégalement possible d’ouvrir autant de fichiers en lecture et/ou en écriture que néces-saire. Par contre, il n’est pas possible (par des moyens simples) d’ouvrir un fichier àla fois en lecture et en écriture. Si l’on souhaite qu’un programmemodifiele contenud’un fichier, il est nécessaire d’effectuer le traitement dela façon suivante :

– ouvrir le fichier à modifier en lecture ;

– lire le contenu du fichier et le stocker dans une structure dedonnées (tableau ouhachage) ;

– fermer le fichier ;

– modifier les données stockées dans la structure ;

– ouvrir à nouveau le fichier, mais en écriture ;

– y écrire les données modifiées ;

– fermer le fichier.

Il est également possible d’utiliser le principe d’écriture dans un fichier auquel onsouhaite simplementajouterde nouvelles lignes de texte. Il faut dans ce cas utiliser lessymboles>> au lieu de> lors de l’appel à la fonctionopen. Dans ce cas, si le fichierindiqué existe déjà, son contenu n’est pas supprimé comme dans le cas d’une ouverturesimple. Les instructions d’écriture parprint dans ce fichier placeront de nouvelleslignes de texte à la suite de celles qui s’y trouvent déjà. Ce type d’ouverture est trèsutile lorsque l’on souhaite accumuler dans un fichier des informations calculées pardes programmes différents (ou un même programme traitant des données différentes).

Page 147: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Les bases de Perl 155

3.9. Arguments d’un programme

Un programme Perl peut recevoir des arguments, c’est-à-dire des informationsindiquées par l’utilisateur dans la ligne de commande qui permet de lancer l’exécution.Ces arguments (ou paramètres) sont exprimés sous la forme dechaînes de caractères(ou de valeurs numériques) dans un ordre défini par le programme.

Ce type de fonctionnement d’un programme remplace en quelque sorte les com-munications interactives vues jusqu’ici, où le programme demande à l’utilisateur desaisir les données à traiter dans le flux d’entrée standard. La spécification de ces don-nées en tant qu’arguments a généralement pour but d’éviter toute sorte d’interactivitéune fois le programme lancé : cela permet d’automatiser plusfacilement l’exécutiondes programmes.

Le programmeflex-nom-masc-argument.plreprend le fonctionnement deflex-nom-masc.plmais obtient le nom à fléchir directement depuis la ligne de commande.

Listing 3.14 – flex-nom-masc-argument.plExemple d’utilisation d’arguments : flexion d’un nom masculin singulier

1 use strict;2 use locale;3

4 if ( $#ARGV != 0 ) 5 die "Usage : ", $0, " <nom à fléchir>\n";6 7

8 my $nom = $ARGV[0];9 my $pluriel = $nom . "s";

10

11 print "Les flexions de \"", $nom, "\" sont :\n";12 print "un ", $nom, "\n";13 print "des ", $pluriel, "\n";

Ligne de commande :perl flex-nom-masc-argument.pl nom

Exemple :perl flex-nom-masc-argument.pl lapin

Résultat :Les flexions de "lapin" sont :

un lapin

des lapins

Page 148: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

156 Perl pour les linguistes

Les paramètres sont obtenus, du côté du programme lui-même,dans un tableauspécial, nommé@ARGV. Ce tableau contient, dès le début de l’exécution du pro-gramme, les différents paramètres fournis par l’utilisateur dans l’ordre où il les a indi-qués. Il est dès lors important, pour un tel programme, de commencer par vérifier quele nombre de paramètres est bien celui attendu, et d’afficherun message d’erreur dansle cas contraire.

La structure conditionnelle des lignes 4 à 6 vérifie donc que l’utilisateur a biendonné un argument et un seul. Ceci se fait en vérifiant la taille du tableau@ARGV. Sila ligne de commande a été correctement écrite, elle n’indique qu’un seul argument(le nom à fléchir) et donc$#ARGV(qui contient le numéro du dernier élément de@ARGV) vaut zéro. Si ce n’est pas le cas (si l’utilisateur n’a pas donné d’arguments,ou en a donné plus d’un), le programme s’arrête en affichant unmessage d’erreurviala fonctiondie.

Dans ce message, la variable spéciale$06est utilisée : elle contient le nom du fi-chier contenant le programme, et est utilisée ici pour donner à l’utilisateur qui s’esttrompé la syntaxe complète de la ligne de commande à utiliser. L’utilisation de $0permet de garantir un message cohérent même si le nom du fichier contenant le pro-gramme a été changé.

A titre d’exemple, si l’utilisateur omet l’argument et tapela ligne de commandesuivante :

perl flex-nom-masc-argument.pl

la réponse du programme sera :

Usage : flex-nom-masc-argument.pl <nom à fléchir>

Si par contre l’utilisateur a utilisé la bonne syntaxe pour sa ligne de commande, lenom qu’il a fourni comme seul argument sera utilisé pour le traitement. Ce nom estdisponible simplement dans la première case du tableau@ARGV, donc par l’expression$ARGV[0] . Une fois cette donnée obtenue, le traitement se fait de la même façon quedansflex-nom-masc.pl.

3.10. Fonctions

On appelle fonction un ensemble d’opérations prédéfinies dont on peut faire usagedans un programme simplement en l’évoquant par son nom.print , chomp, open, die,etc., sont des fonctions.

6. Il s’agit ici du chiffre zéro, pas de la lettre majuscule O.

Page 149: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Les bases de Perl 157

Mais il est également possible de définir de nouvelles fonctions, afin de faciliterdans un programme l’exécution d’instructions couramment utilisées. On parle égale-ment desous-programmes, puisque la définition d’une telle fonction passe par l’indi-cation d’un sous-ensemble d’instructions au sein d’un programme.

Dans le cas général, une fonction reçoit des arguments (ou paramètres) et retournele résultat d’un calcul basé sur ces arguments.

Le programmeflex-nom-fonction.pleffectue une fois de plus la flexion d’un nomcommun, mais en utilisant une fonction pour effectuer le calcul du pluriel.

Listing 3.15 – flex-nom-fonction.plExemple d’utilisation d’une fonction : flexion d’un nom

1 use strict;2 use locale;3

4 print "Entrez un nom commun singulier :";5 my $nom = <STDIN>;6 chomp $nom;7

8 print "Le pluriel de \"", $nom, "\" est : ", pluriel( $nom ), "\ n";9

10 sub pluriel 11 my $singulier = shift @_;12 my $plur = $singulier . "s";13 return $plur;14

Ligne de commande :perl flex-nom-fonction.pl

Exemple de déroulement :Entrez un nom commun singulier : lapin

Le pluriel de "lapin" est : lapins

Un programme utilisant une fonction comporte deux parties :

– un bloc principal, comme tous les programmes vus jusqu’ici, mais dans lequelcertaines instructions peuvent faire appel à la fonction définie ;

– un bloc de définition de la fonction, introduit par le mot-clésub.

flex-nom-fonction.pldéfinit et utilise la fonctionpluriel . L’instruction de laligne 8 contient un appel à cette fonction, qui est définie parles lignes 10 à 14.

Le nom d’une fonction est défini de façon arbitraire, comme lesont les noms devariables. Son utilisation se fait simplement en utilisantson nom, et en précisant les

Page 150: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

158 Perl pour les linguistes

paramètres entre parenthèses. Ainsi, l’expression :pluriel( $nom )correspond au résultat du traitement de la chaîne$nom par la fonctionpluriel .

La fonction elle-même est donc définie dans un bloc d’instructions introduit parsub suivi du nom de la fonction. Sa position par rapport au code principal du pro-gramme importe peu, et l’usage veut que les fonctions soientdéfinies en fin de pro-gramme, comme c’est le cas ici.

Le corps de la fonctionpluriel se décompose en trois étapes :

– récupération du paramètre, autrement dit le nom singulierà fléchir (ligne 11) ;

– calcul du pluriel par ajout d’uns final (ligne 12) ;

– retour du résultat (ligne 13).

Les paramètres d’une fonction lui sont communiqués sous la forme d’un tableaudisponible dans la variable spéciale@_. Comme toutes les variables spéciales, ce ta-bleau n’a pas besoin d’être déclaré et contient, dans l’ordre, les différents paramètrescommuniqués à la fonction lors de son appel. Dans le cas de la fonctionpluriel ,ce tableau ne contient qu’un seul paramètre, le nom à fléchir.Ce nom va être recopiédans la variable locale$singulier . Cette copie se fait en utilisant la fonctionshiftqui, appliquée à un tableau, renvoie son premier élément.shift a également commeeffet desupprimerce premier élément du tableau, ce qui a comme conséquence depermettre la récupération de plusieurs paramètres à la suite par des appels successifs.Il aurait été équivalent de recopier le nom à fléchir par l’instruction :

my $singulier = $_[0];autrement dit en prenant le premier élément du tableau@_.

Une fois le nom à fléchir obtenu, on calcule sa forme au plurielde la façon clas-sique pour les noms réguliers, en y ajoutant uns, et en stockant le résultat dans lavariable scalaire$plur .

Une fonction a pour but de calculer une valeur, et de la communiquer comme va-leur de retour à l’instruction qui l’a invoquée. Ceci se faitsimplement par l’utilisationde la fonctionreturn , suivie de la valeur de retour. L’instructionreturn a égalementpour effet de terminer l’exécution de la fonction ; toute instruction qui la suivrait neserait pas exécutée.

Cet exemple de programme n’a pour seul but que de montrer la syntaxe de défi-nition et d’emploi d’une fonction. Toutefois, les avantages d’une fonction seront vusplus nettement dans des programmes plus complexes, mais on peut déjà les citer :

– une fonction permet destructurerun programme, en séparant les différents trai-tements en différentes sous-parties ;

Page 151: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Les bases de Perl 159

– une fois une fonction définie, elle peut être invoquée plusieurs fois dans un pro-gramme. Ainsi, on a tout intérêt à rassembler dans une fonction un ensemble d’ins-tructions que l’on trouve répétées à plusieurs endroits d’un même programme;

– les fonctions permettent une constructionmodulaired’un programme complexe :elles peuvent être aisément importées d’un programme vers un autre, et sont le moyenle plus efficace pour assembler un code complexe écrit par plusieurs personnes et/ousur des périodes de temps longues ;

– enfin, dans certains cas, la syntaxe de Perl nécessite la définition de fonctions,comme il sera présenté dans l’emploi de techniques avancées(voir notamment le cha-pitre 9).

REMARQUE.– Il est fortement conseillé de n’utiliser, au sein d’une fonction, que desvariableslocales, c’est-à-dire déclarées parmy dans le corps de la fonction. Ceci per-met de rendre autonome la fonction par rapport au programme qui l’utilise, et garantitla modularité du traitement ainsi défini.

3.11. Autres notions

Les différents programmes qui ont été présentés dans ce chapitre donnent un pre-mier aperçu des principes de la programmation en Perl. Tous ces programmes peuventêtre utilisés tels quels, mais ils peuvent aussi servir de base à des modifications et desadaptations.

3.11.1. Erreurs de programmation

Une étape importante dans l’apprentissage de la programmation en Perl consisteen l’écriture d’un programme, par opposition à l’utilisation d’un programme dispo-nible. Cette étape nécessite parfois plusieurs essais avant de parvenir à un programmesatisfaisant. Nombre de ces essais conduisent régulièrement le programmeur à pro-duire des erreurs, qui empêchent la bonne exécution du programme. Les erreurs deprogrammation sont de deux types :

– les erreurs de syntaxe. Ces erreurs sont généralement dues à une faute de frappe,ou à une méconnaissance de la syntaxe générale du langage de programmation. Ellesempêchent tout simplement l’exécution du programme, car l’interpréteur Perl ne par-vient pas à « comprendre » le code du programme. Les cas classiques d’erreurs desyntaxe sont :

- une faute dans l’écriture d’un mot-clé du langage (par exempleprunt au lieudeprint ) ;

- un oubli de signe de ponctuation (point-virgule en fin d’instruction ; guille-mets, parenthèses ou accolades non équilibrés) ;

- une variable non déclarée ou mal orthographiée.

Page 152: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

160 Perl pour les linguistes

Dans ces différents cas, l’interpréteur perl, au moment où il est invoqué dans uneligne de commande, indiquera par un court message qu’il a rencontré un problèmedans son interprétation du code. Ce message (en anglais) apparaîtra dans le terminal,et le programme ne s’exécutera pas. Le langage Perl est très laconique dans sesmessages d’erreurs, et indiquera globalement le problème et sa localisation. Voici unexemple de message d’erreur :

String found where operator expected at flex-nom-masc.pl l ine 7, near"prunt "Entrez un nom commun masculin singulier : ""

(Do you need to predeclare prunt?)syntax error at flex-nom-masc.pl line 7, near "prunt "Veuil lez entrerun nom commun masculin singulier : ""Execution of flex-nom-masc.pl aborted due to compilation e rrors.

Ce message indique qu’une erreur de syntaxe a été détectée par l’interpréteur dansle programmeflex-nom-masc.plà la ligne 7, près de l’instruction :

prunt "Entrez un nom commun masculin singulier : ";

L’interpréteur indique (timidement) que le problème vientpeut-être du motpruntqui n’aurait pas été prédéclaré comme variable. L’attitudeconseillée face à de telsmessages est simplement d’examiner plus précisément la ligne indiquée, puis de re-monter vers le début du code. Il faut en effet prendre en compte le fonctionnement del’interpréteur, qui indique une erreur au moment où il s’en rend compte. Dans biendes cas, l’erreur elle-même existe bien avant l’endroit indiqué. C’est notamment lecas lorsqu’il y a des erreurs dans les signes de ponctuation (oubli de guillemets ou depoints-virgules) ;

– les erreurs de sémantique. Ces erreurs sont celles qui n’empêchent pas l’exé-cution du programme, mais qui entraînent un comportement autre que celui attendu.Elles ne peuvent pas être détectées par l’interpréteur, quise limite aux erreurs de syn-taxe, et sont de fait les plus difficiles à identifier et à corriger. On se rend compte dela présence d’une telle erreur lorsque le programme a un comportement différent decelui attendu : arrêt immédiat, affichage de résultats erronés, figement. Ces erreurspeuvent provenir de différentes sources :

- oubli de certaines instructions, par exemple l’initialisation d’une variable, oula suppression d’une fin de ligne dans une chaîne ;

- utilisation d’un mauvais opérateur ou d’une mauvaise fonction ;- mauvais ordonnancement des traitements ;- mauvaise organisation des structures de contrôle.

Cette liste ne peut malheureusement pas être exhaustive. Lecomportement à adop-ter face à de tels problèmes est de valider une à une les différentes étapes du traitement,afin de cerner celle qui pose problème. Ceci peut se faire aisément en ajoutant au fildu code des instructions affichant des messages sur le statutdu programme au fur et à

Page 153: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Les bases de Perl 161

mesure de son déroulement. Il est par exemple souvent très utile d’afficher des mes-sages d’étapes du typelecture des données terminée. L’absence d’apparition d’un telmessage à l’exécution indiquera par exemple que le bloc d’instructions où il se trouven’est pas exécuté, peut-être à cause d’une conditionnelle mal conçue. Il est égalementutile d’afficher le contenu des variables principales au furet à mesure, afin de contrôlerle bon déroulement des traitements.

3.11.2. Autres composants du langage Perl

Les exemples présentés dans ce chapitre couvrent l’essentiel de la syntaxe du lan-gage Perl qui sera utilisé dans les programmes présentés dans le reste de l’ouvrage.Ce n’est toutefois qu’un premier aperçu des fonctionnalités du langage, qui contientde nombreuses autres structures syntaxiques et fonctions prédéfinies. Ces fonctionna-lités seront présentées au fur et à mesure des différents traitements, et une liste desfonctions prédéfinies utilisées est disponible en annexe A5.

Page 154: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

162

Page 155: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

CHAPITRE 4

Expressions régulières

4.1. Généralités et définition

Une majorité des manipulations de chaînes de caractères présentées dans cet ou-vrage sont basées sur un outil très précieux : les expressions régulières. Elles peuventêtre utilisées dans les éditeurs de textes, dans certains utilitaires en ligne de commandeet bien entendu dans les programmes Perl. Les expressions régulières permettent :

1) de tester si une chaîne correspond à un schéma particulier;

2) d’en extraire des sous-chaînes ;

3) de modifier une chaîne en remplaçant ou supprimant certaines de ses parties.

Il s’agit donc d’un outil à usages multiples, dont la maîtrise est toutefois difficilemais largement rentable. Ce chapitre passe en revue les différentes fonctionnalités desexpressions régulières, présente leur syntaxe, leur utilisation en Perl et les mécanismesassociés.

Avant tout, une expression régulière est une façon concise de représenter une fa-mille de chaînes de caractères. Cette famille est décrite comme un ensemble de formespossibles, laissant notamment la place à des éléments pouvant varier d’une chaîne àl’autre. On peut ainsi utiliser une expression régulière pour représenter de façon for-melle ce qu’en français on appellerait :

– les mots finissant par-able;

– les mots finissant par-ableou -ible, éventuellement avec unsfinal ;

– les radicaux de l’infinitif des verbes du premier groupe ;

– les séquences du typeX deD Y dans un texte oùX etY sont des mots simpleset ouD est un déterminant quelconque ;

163

Page 156: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

164 Perl pour les linguistes

– les séquences du typeX de Y deZ de...aussi longues que possibles dans untexte.

A chaque famille de ce type correspond une expression régulière, utilisable parun logiciel ou un langage de programmation, et définissant defaçon non ambiguëles chaînes possibles. En fait, il existe généralement plusieurs expressions régulièreséquivalentes permettant de décrire une même famille.

Nous considérons dans cette présentation que les chaînes ainsi définies sontconstruites à l’aide de n’importe quels caractères, (c’est-à-dire des lettres, mais aussides chiffres, des espaces, des signes de ponctuation, etc. L’ensemble de ces caractèresest appeléalphabetdans la suite de ce chapitre ; ce terme n’est donc pas limité auxcaractères correspondant aux lettres (dea àz).

4.2. Expressions régulières de base

Il existe différents niveaux de complexité dans les expressions régulières. Nouscommençons par le niveau fondamental qui, bien que suffisanten théorie, n’est pasnécessairement le plus apte à résoudre des problèmes complexes. Il permet toutefoisde définir les principes généraux de construction et de fonctionnement d’une expres-sion aussi complexe soit-elle.

4.2.1. Principe de correspondance

Une expression régulière est définie pour être mise en correspondance avec une ouplusieurs chaînes de caractères. On dira qu’il y a correspondance entre une chaîne etune expression si la chaîne fait partie de l’ensemble défini par l’expression régulière.Ainsi, si l’expressionR définit les chaînes se terminant parable, alorsR est en cor-respondance avec les chaînestable, able, autoréférençable, etc. Mais elle n’est pas encorrespondance avectableauouabl.

Pour des soucis de notation, nous écrivons les expressions régulières entre deuxbarres obliques :/comme ceci/ . Les chaînes mises en correspondance sont notéesen caractères penchéscomme cela. De plus, pour les expressions les espaces serontnotés .

4.2.2. Anatomie d’une expression régulière

Une expression régulière est composée de symboles parmi lesquels on trouve :

– tout caractère de l’alphabet comme :a A é , : @ ;

Page 157: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Expressions régulières 165

– des caractères spéciaux, ou métacaractères, permettant d’exprimer des opéra-tions particulières ou des assertions comme :* | ( ) ^ $ .

Pour étudier le rôle de ces différents métacaractères, nousprésentons les princi-pales opérations à l’œuvre dans la formation d’une expression régulière.

4.2.3. Expressions atomiques

L’expression régulière la plus simple qui soit est celle quiest réduite à un caractèrede l’alphabet. Cette expression est en correspondance avecn’importe quelle chaînequicontientce caractère.

L’expression/a/ est en correspondance avec les chaînes :a, ara, lapin, cheval,orang-outan, etc., puisque toutes ces chaînes contiennent un caractèrea.

4.2.4. Concaténation

La concaténation est l’opération fondamentale permettantde construire deschaînes de caractères à partir des symboles de l’alphabet. On utilise donc la conca-ténation dans une expression régulière pour exprimer le fait que l’on cherche à définirun ensemble de chaînes qui contient uneséquencede caractères. Dans ce cas, l’ex-pression régulière est construite simplement en juxtaposant les caractères en question.

L’expression/ar/ est en correspondance avec les chaînes :ara, araignée, canard,jaguaretc. puisque toutes ces chaînes contiennent une séquence decaractèresar.

4.2.5. Disjonction

La disjonction, ou alternative, est la possibilité de définir un ensemble de chaînescouvrant plusieurs possibilités, par exemple les chaînes contenant unz ou unw. Cha-cune de ces possibilités peut être obtenue par une expression régulière (ici/z/ et/w/ ), mais on peut définir l’ensemble par un seule expression régulière. Il suffit dejoindre les deux expressions en une seule par une barre de disjonction, ce qui donne/z|w/ . Cette expression est en correspondance avec les chaînes :lézardetwapiti.

4.2.6. Critères de position

Il est possible de décrire au moyen d’une expression régulière des chaînes conte-nant des caractères à des positions précises. Les deux positions fondamentales sont ledébut et la fin de la chaîne, qui se notent respectivement^ et $. (Attention à ne pas

Page 158: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

166 Perl pour les linguistes

confondre les fins de lignes (\n ) et les fins de chaînes ($).) Les critères de positionssont également appelésassertions.

Ainsi, l’expression régulière/^a/ est en correspondance avec toute chaîne com-mençant par una (ara, araignée, etc.) et/s$/ est en correspondance avec toute chaînese terminant pas uns (ours, brebis, etc.).

L’expression régulière/^ara$/ est, elle, en correspondance avec une seulechaîne :ara, puisque la séquenceara doit se situer à la fois au début et à la fin de lachaîne.

4.2.7. Fermeture

La dernière opération fondamentale est celle qui permet d’indiquer qu’une partiedu motif défini par une expression régulière peut se répéter dans les chaînes mises encorrespondance. On utilise pour cela la notion defermeture, définie par l’étoile :* . Cesymbole, placé derrière un caractère (ou une expression plus complexe comme nousle verrons par la suite) indique que celui-ci peut se répéterun nombre quelconque defois dans la chaîne, y compris aucune.

Ainsi, l’expression/^ * $/ est en correspondance avec toute chaîne ne contenantquedes espaces (un seul espace, deux espaces, etc.) mais également avec la chaînevide (aucun espace ni aucun autre caractère).

Sauf indication contraire, l’étoile ne s’applique qu’au caractère situé immédiate-ment à sa gauche. L’expression/il * e/ est ainsi en correspondance avec toute chaînecontenant uni, suivi d’un nombre quelconque del, suivis d’une. C’est le cas deschaînes :crocodile (un l ), chenille (deuxl ), chien (aucunl ).

Dans certains cas, la fermeture ne permet pas d’être suffisamment précis. Ainsi,l’expression/a * / est en correspondance avec toute chaîne de caractères contenantun nombre quelconque dea (y compris aucun), c’est-à-dire avec n’importe quellechaîne de caractères.

4.2.8. Parenthèses et priorité des opérateurs

Une expression régulière fait généralement appel à plusieurs opérations parmi lesquatre mentionnées. Lorsque c’est le cas, il convient d’être bien conscient des règlesde priorité qui gèrent l’interprétation de l’expression dans son ensemble.

La priorité des opérateurs est la suivante :

1) fermeture (* ) ;

Page 159: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Expressions régulières 167

2) concaténation (y compris les critères de position) ;

3) disjonction (| ).

Cela veut par exemple dire que dans l’expression/ab * / la fermeture ne s’ap-plique qu’au caractèreb, et correspond à toute chaîne contenant una suivi d’unnombre quelconque deb, et non un nombre quelconque de séquencesab.

De même, l’expression/il|r/ est en correspondance avec toute chaîne conte-nant soit une séquenceil soit une séquencer. Elle n’est pas interprétée au sens de « uni suivi d’un l ou d’unr ».

L’expression/ab * |r/ est quant à elle en correspondance avec les chaînes conte-nant soit una suivi d’un nombre quelconque deb, soit unr.

Lorsque les règles de priorité vont à l’encontre de ce que l’on souhaite, il est néces-saire d’utiliser des parenthèses. Ces symboles supplémentaires s’utilisent pour formerdes sous-expressions dans lesquelles les règles de priorité sont appliquées localement.Une analogie classique peut être faite avec les expressionsarithmétiques. Dans ces ex-pressions, la multiplication est prioritaire par rapport àl’addition, si bien que5+3×2est interprété comme5 + (3 × 2) et vaut11. Si l’on souhaite que l’addition se fasseavant la multiplication, il faut écrire(5 + 3)× 2 qui vaudra16.

Ainsi, pour que la disjonction s’applique à l’intérieur d’un élément d’une séquenceconcaténée, par exemple pour décrire les chaînes contenantun i ou un l, suivi d’unr, il faut utiliser l’expression :/(i|l)r/ . Pour représenter une chaîne commençantpar uns suivi d’un nombre quelconque de voyelles puis d’un autres on doit utiliser :/^s(a|e|i|o|u) * s/ .

De même, pour indiquer à l’aide d’une fermeture la répétition possible d’une sé-quence de caractères, il est nécessaire de placer celle-ci entre parenthèses afin quel’opérateur* s’applique à l’ensemble. Ainsi, l’expression/^(lou) * $/ définit l’en-semble des chaînes formées uniquement de séquenceslou, c’est-à-direlou, loulou,etc., mais aussi la chaîne vide.

Les parenthèses ne sont pas nécessaires si elle ne font que confirmer les prioritésnaturelles des opérateurs. Elles ne modifient alors pas le sens de l’expression, commepour /(as)|r/ qui est équivalente à/as|r/ . Elles améliorent en revanche la li-sibilité des expressions et peuvent servir à la mémorisation de segments de chaîne(voir paragraphe 4.6.1).

Page 160: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

168 Perl pour les linguistes

4.2.9. Métacaractères et échappement

Les différentes opérations à l’œuvre dans une expression régulière s’exprimentpour la plupart en utilisant des symboles ou des caractères spéciaux. C’est le cas dessymboles suivants que nous avons vus jusqu’ici :

| * ^ $ ( )

Ces symboles sont aussi appelésmétacaractères.

Or, il est parfois nécessaire de définir des expressions régulières qui contiennentces caractères en tant qu’éléments de chaînes. Il faut alorsneutraliser leur statut demétacaractère ; c’est par exemple le cas si l’on veut décrirel’ensemble des chaînescontenant une parenthèse.

La neutralisation est réalisée en échappant ces caractères, c’est-à-dire en les faisantprécéder d’une barre oblique inverse\ (appelée encorebackslash). Ainsi, l’expres-sion régulière qui est en correspondance avec toute chaîne contenant une parenthèseouvrante est :/\(/ .

Nous verrons par la suite d’autres métacaractères, et la liste complète est dispo-nible en annexe A5 (paragraphe A5.8.1, page 479). Le principe est le même pour tousces caractères. Notons que la barre oblique inverse étant elle-même un métacaractère,il est nécessaire de la doubler pour citer le caractère en question : \\ .

Le caractère\ permet aussi de citer certains caractères spéciaux qui sontplusdifficiles à manipuler comme la tabulation représentée par la séquence\t et la fin deligne notée\n .

REMARQUE.– Il arrive couramment qu’on attribue à tort le statut de métacaractère àcertains signes de ponctuation. Dans ce cas, les faire précéder d’un\ ne pose pas deproblèmes à Perl, qui tolère les échappements superflus.

4.3. Expressions régulières étendues

Si les éléments que nous avons vus jusqu’ici forment le noyaudu langage des ex-pressions régulières, il reste difficile de s’y limiter pourreprésenter des ensembles dechaînes assez courants. Par exemple, si l’on souhaite exprimer l’ensemble des chaînescomposées de lettres commençant par und et se terminant par une, l’expression cor-respondante est relativement verbeuse :

/^d(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x |y|z) * e$/

Page 161: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Expressions régulières 169

Et encore, cette expression ne contient pas les lettres majuscules ni celles qui com-portent des diacritiques. Mais si l’on souhaite préciser qu’il y a au moins une lettreentre led et lee, l’expression est plus longue encore, puisqu’il faut explicitement in-diquer la lettre suivant immédiatement led (l’étoile incluant l’absence de l’élémentauquel elle s’applique) :

/^d(a|b|c...y|z)(a|b|c...y|z) * e$/

Bien entendu, les points de suspension sont à remplacer par l’ensemble des lettres.

Trois types d’extensions permettent d’exprimer simplement les ensembles de cetype. La première concerne la possibilité de définir de façonconcise des ensemblesde caractères, la deuxième permet de contrôler plus précisément le fonctionnement del’opérateur de fermeture et la troisième introduit de nouveaux critères de position.

4.3.1. Classes de caractères

Il existe deux possibilités d’exprimer des ensembles de caractères dans une expres-sion régulière. La première est de faire appel à des classes prédéfinies. La seconde estde définir de nouvelles classes de façon concise.

4.3.1.1.Classes prédéfinies

Les symboles ou séquences de symboles suivants permettent de définir un en-semble de caractères :

Notation Caractères correspondants. (point) Tout caractère, sauf le caractère de fin de ligne\w Toute lettre1, chiffre ou caractère souligné (_)\s Tout caractère d’espacement (espace, tabulation, retour àla ligne)\d Tout chiffre (de0 à9)\W Tout caractère sauf une lettre1, un chiffre ou le caractère souligné\S Tout caractère sauf un caractère d’espacement\D Tout caractère sauf un chiffre\pL Toute lettre\PL Tout caractère sauf une lettre\pP Tout signe de ponctuation

1. Les lettres concernées par la classe\w (et donc exclues de son complémentaire\W) ne com-prennent les lettres accentuées que lorsque le programme manipulant l’expression régulière estlocalisé. Voir l’annexe A3 pour plus de détails.

Page 162: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

170 Perl pour les linguistes

La classe la plus utile est bien entendu la classe générique notée par le point. Ellepermet par exemple de définir très facilement par une expression régulière l’ensembledes chaînes commençant par und et finissant par une, quelle que soit la séquence decaractères qui les sépare :/^d. * e$/ .

La deuxième série contient des classes prédéfinies classiques. La troisièmecontient des classes complémentaires, c’est-à-dire définissant l’ensemble des carac-tères qui ne font pas partie d’une des classes précédentes. Les classes de la quatrièmesérie sont définies en se basant sur les propriétés Unicode des caractères. Ces proprié-tés sont décrites en annexe A2.

Les moyens mnémotechniques pour les deuxième et troisième classes sont les sui-vants : lorsque la classe est définie par une lettre minuscule, cette lettre est la premièredes mots anglaisword, spaceet digit. Lorsque c’est une lettre majuscule, il s’agit ducomplémentaire de l’ensemble correspondant à la lettre minuscule.

L’expression/^d. * e$/ est en correspondance avec des mots simples (commedinde) mais aussi avec des séquences de plusieurs mots (commedindon de la farce).Imposer qued et e ne soient séparés que par des lettres (et donc empêcher la corres-pondance avec la seconde chaîne) peut s’exprimer tout aussisimplement en utilisantla classe\pL , ce qui donne :/^d\pL * e$/ .

4.3.1.2.Définition de classes

Dans les cas où aucune des classes prédéfinies ne correspond àce que l’on sou-haite, il est possible de définir de façon concise un ensemblede caractères en uti-lisant une notation entre crochets. Ainsi, l’expression/[aeiou]/ est équivalenteà /(a|e|i|o|u)/ et exprime l’ensemble des voyelles non accentuées. On peutainsi noter une petite économie grâce à l’omission des barres de disjonction. Cettenotation peut bien sûr s’intégrer à des expressions plus complexes, comme dans :/^d[aeiou] * s$/ qui définit les chaînes commençant par und, finissant par unset contenant entre les deux un nombre quelconque de voyelles.

Il est également possible de définir des classes en utilisantl’ordre lexicographiquedes caractères. Ainsi,[a-z] désigne toute lettre minuscule (c’est-à-dire tout carac-tère situé lexicographiquement entrea et z inclus).

Il est possible de combiner les deux notations et de définir une classe de caractèresen utilisant plusieurs intervalles, comme dans[a-zA-Z] qui représente toute lettre,majuscule ou minuscule. L’ordre lexicographique pose toutefois deux problèmes :

– il n’est absolument pas intuitif en dehors des lettres, même s’il est défini pourtout caractère manipulable ;

– l’intervalle [a-z] ne contient pas les lettres accentuées ou dotées de diacri-tiques commeé ouç.

Page 163: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Expressions régulières 171

Pour plus de détails sur l’ordre des caractères et sur la place des lettres accentuées,voir l’annexe A2. Dans tous les cas, il est préférable d’utiliser la classe prédéfinie\pLquand on veut désigner toute lettre, accentuée ou non.

Le tiret utilisé pour définir des intervalles est de ce fait unmétacaractère. Il estdonc nécessaire de le faire précéder d’une barre oblique inverse pour le citer dans uneclasse. Par exemple,[;\-,] est une classe comprenant le point-virgule, le tiret et lavirgule.

Il est possible d’étendre avec cette notation les classes prédéfinies, en les insérantentre crochets. Ainsi, la classe[\pL\-] comprend toutes les lettres et le tiret. Lepoint (. ) dans une classe de caractères indique bien le caractère point et non n’importequel caractère, puisque cette classe universelle prédéfinie ne peut de toute façon êtreétendue.

Une dernière utilisation courante des classes définies est celle qui consiste àconstruire des classes complémentaires, c’est-à-dire desclasses ne contenantpaslescaractères listés. Ceci se note en plaçant le symboleˆ au début de la liste. Ainsi[^aeiou] correspond à tout caractère qui n’est pas une voyelle minuscule. [^ ]correspond à tout caractèresauf un espace.

Il n’est malheureusement pas possible avec ce mécanisme de définir une classe dutype « toutX saufY », comme par exemple « toute lettre sauf une voyelle » (donctoute consonne) : la notion de classe complémentaire s’entend toujours par rapport àl’alphabet entier. Pour le cas des consonnes, il est toutefois possible de définir écono-miquement cet ensemble en utilisant plusieurs intervalles: [b-df-hj-np-tv-z] .

4.3.2. Fermetures complexes

Dans les expressions régulières de base, le seul opérateur de fermeture disponibleest l’étoile (* ) qui couvre un nombre quelconque d’occurrences de l’expression àlaquelle elle s’applique, y compris aucune.

Dans nombre de situations, cet opérateur n’est pas parfaitement adapté ; il existeainsi une série d’opérateurs de fermeture dont le fonctionnementsyntaxique est stricte-ment le même que celui de l’étoile , mais qui permettent de mieux contrôler le nombred’occurrences pouvant être mis en correspondance. Ils sontprésentés dans le tableausuivant (n etmétant des nombres entiers) :

Page 164: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

172 Perl pour les linguistes

Opérateur Signification

* 0 ou plusieurs occurrences+ 1 ou plusieurs occurrences? 0 ou 1 occurrence (optionnalité)n n occurrencesn,m entren et moccurrencesn, au moinsn occurrences,m au plusmoccurrences

Ainsi, pour reprendre un exemple précédent, l’ensemble deschaînes de caractèrescommençant par und, finissant par une et comprenant au moins un caractère entreles deux se définit par l’expression régulière/^d.+e$/ .

L’opérateur d’optionnalité (?) est très utile lorsque l’on souhaite évoquer un motpossédant ou non une terminaison, comme par exemple la marque du pluriel régulieren français. Il suffit en effet d’indiquer que les final est optionnel, et l’on couvreainsi les formes au singulier et au pluriel en une seule expression. Par exemple,/^moutons?$/ est en correspondance à la fois avecmoutonet moutonsmais pasavecmoutonssce qui serait le cas avec/^moutons * $/ .

Les opérateurs de fermeture permettant de contrôler précisément le nombred’occurrences (n,m ) sont essentiellement utilisés pour la manipulation dechaînes de caractères contenant plusieurs mots. Par exemple, l’expression :/^un (\pL+ )1,3lapin$/ est en correspondance avec toute chaîne com-mençant parun, finissant parlapin et comprenant un, deux ou trois mots dans l’in-tervalle. Elle est par exemple en correspondance avecun petit lapinmais pasun trèstrès joli petit lapin.

4.3.3. Frontières de mots

La dernière fonctionnalité avancée des expressions régulières est une extension descritères de position. Les critères^ et $ vus précédemment, correspondent respective-ment au début et à la fin de la chaîne. Dans le cas d’une chaîne contenant un segmentde texte, il peut être très utile de faire appel à la notion defrontière de motcommecritère de position. On appelle frontière de mot (notée\b ) la position qui sépare uncaractère formateur de mot (faisant partie de la classe\w ) et un caractère qui n’en faitpas partie (faisant donc partie de la classe complémentaire\W). Comme et $, l’ex-pression\b est donc en correspondance avec des positions, et non des caractères. Pourrésumer l’utilisation de cet opérateur, voici la place des frontières de mots (indiquéespar des barres verticales |) dans la chaîne :L’exemple est-il suffisant, au moins ?:

|L|’|exemple| |est|-|il| |suffisant|, |au| |moins| ?

Page 165: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Expressions régulières 173

Le début et la fin de la chaîne sont également des frontières demots si le premier oule dernier caractère sont des caractères formateurs de mots. C’est le cas de la positionà gauche duL initial, mais pas de celle qui est à droite du point d’interrogation final.

Ces marqueurs sont utilisés pour repérer des éléments de texte correspondant à desmots entiers et non des segments quelconques. Par exemple, l’expression/\bde\b/ne sera en correspondance qu’avec une chaîne contenant le mot de, mais pas avec unechaîne ne contenant qu’un mot comprenant la séquencede, commedinde. L’utilisationdes frontières de mots évite d’avoir à énumérer tous les séparateurs envisageables(espaces, début et fin de ligne, signes de ponctuation, etc.). Il faut toutefois noter quele tiret et l’apostrophe, n’étant pas des caractères formateurs de mots au sens de laclasse\w , ils sont considérés comme des frontières lorsqu’ils sont contigus à unelettre.

4.4. Syntaxe Perl pour la correspondance

L’utilisation des expressions régulières en Perl se fait dedifférentes façons. Nousnous intéressons plus précisément ici au test de correspondance simple.

Etant donné une expression régulière/ ER/ et une chaîneC, le test permettant desavoir s’il y a ou non correspondance entre les deux s’exprime de la façon suivante :

C =~ / ER/

Cette expression s’utilise comme toute expression de comparaison, c’est-à-diredans un contexte booléen comme la condition d’unif ou d’unwhile.

Ainsi, le programmetermine-s.pl (listing 4.1) vérifie, pour une chaîne don-née en entrée standard si elle se termine ou non par uns, et affiche la réponse.

Listing 4.1 – termine-s.plTest d’une terminaison ens par expression régulière

1 use locale;2 use strict;3

4 print "Entrez un mot : ";5 my $chaine = <STDIN>;6 chomp $chaine;7

8 if ( $chaine =~ /s$/ ) 9 print "Votre mot se termine par un s\n";

10 11 else 12 print "Votre mot ne se termine pas par un s\n";13

Page 166: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

174 Perl pour les linguistes

Ligne de commande :perl termine-s.pl

Exemple de déroulement :(les chaînes saisies par l’utilisateur sont en gras)Entrez un mot : lapins

Votre mot se termine par un s

Les détails de la syntaxe de ce programme sont présentés au chapitre 3. La compa-raison de la chaîne entrée avec l’expression régulière/s$/ ne peut donner que deuxvaleurs : VRAI ou FAUX.

Il est également possible de modifier légèrement la mise en correspondance par lebiais d’options placées derrière la seconde barre oblique/ qui délimite l’expressionrégulière. L’option pertinente pour ce test est représentée par la lettrei . Elle indiqueque la mise en correspondance ne doit pas prendre en compte les différences de casse(majuscule/minuscule) entre la chaîne et l’expression régulière. Ainsi, changer l’ex-pression de comparaison de la ligne 8 par :

if ( $chaine =~ /s$/i )

permettra d’obtenir une correspondance si la chaîne en entrée se termine par unS ouun s. L’insensibilité à la casse vaut bien entendu pour les lettres qui composent l’ex-pression régulière : avec l’optioni activée, les expressions/s$/ , /S$/ et /[sS]$/sont strictement équivalentes.

Puisque les expressions régulières en Perl doivent être encadrées par des barresobliques (/ ), ce caractère devient de fait un métacaractère, et doit être précédé d’unebarre oblique inverse (\ ) quand on souhaite le citer en tant que tel dans une expression.

4.5. Mécanismes de correspondance

Nous nous sommes jusqu’ici contentés d’envisager les expressions régulièrescomme façon de définir un ensemble de chaînes de caractères. Leur principale moded’utilisation est en effet de vérifier l’appartenance d’unechaîne à l’ensemble ainsi dé-fini, ce qui permet de filtrer ou de repérer des séquences précises dans un ensemble dedonnées textuelles (liste de mots ou texte).

Mais l’utilité des expressions régulières dépasse la simple définition d’ensemblesde chaînes : elles permettent en effet aussi de manipuler deschaînes, d’extraire dessous-chaînes et de modifier tout ou partie de celles-ci. Avant d’aborder ces utilisationsplus complexes, détaillons le fonctionnement de la mise en correspondance entre uneexpression régulière et une chaîne de caractères analysée.

Page 167: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Expressions régulières 175

4.5.1. Sous-chaînes de caractères et sous-expressions

Même si la correspondance entre une chaîne et une expressionpeut se concevoirglobalement, cette association s’établit en fait entre leséléments de l’expression etceux de la chaîne (c’est-à-dire des segments, également appelés sous-chaînes). Lafigure 4.1 montre par exemple l’association entre l’expression /b.[aeiou]/ et lachaîneblaireau:

blaireau

[aeiou]//b.

Figure 4.1. Correspondance entre l’expression/b.[aeiou]/ et la chaîneblaireau

Le cas présenté ici est simple : la correspondance se fait sans aucune ambiguïté (iln’y a notamment qu’un seul caractèreb dansblaireau, et chaque élément de l’expres-sion correspond à un seul caractère de la chaîne).

La correspondance devient plus complexe lorsque l’expression régulièrecontient des fermetures ou des disjonctions entre segments. La figure 4.2montre les différentes possibilités d’associations entreles éléments de l’expression/(bl|re)[aeiou]+/ et la chaîneblaireau.

ab airel3

21

u4

Figure 4.2. Ambiguïtés de correspondance pour entre l’expression/ (bl|re)[aeiou]+/ et la chaîneblaireau

Cette figure illustre les 4 possibilités d’association, correspondant aux quatre sous-chaînes deblaireau: bla, blai, reaet reau. Lors de la mise en correspondance, toute-fois, une seule des quatre possibilités est sélectionnée par le programme qui effectuel’association, en l’occurrence la deuxième (blai).

Ce choix découle des différentes règles prises en compte lors de la mise en corres-pondance.

4.5.2. Les règles de la correspondance

Lors de la mise en correspondance d’une expression avec une chaîne de caractères,deux principes s’appliquent dans l’ordre suivant :

Page 168: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

176 Perl pour les linguistes

1) de gauche à droite. La mise en correspondance s’effectue de gauche à droite,donc dans le sens d’écriture des langues occidentales. La partie de la chaîne mise encorrespondance sera la première à gauche quand plusieurs possibilités d’associationsont envisageables ;

2) quand c’est possible, autant que possible.Si une expression régulière peuts’appliquer à un endroit de la chaîne, elle s’y appliquera enimpliquant le plus grandnombre de caractères. On fait référence à ce principe sous leterme degloutonneriedes opérateurs de fermeture.

Ces deux règles permettent d’expliquer le choix de la sous-chaîneblai lors de lamise en correspondance de l’expression/(bl|re)[aeiou]+/ et deblaireau. Lapremière règle sélectionne les deux sous-chaînes les plus àgauche parmibla, blai, reaet reau, c’est-à-direbla et blai. La seconde règle sélectionne ensuiteblai de préfé-rence àbla : blai contient un caractère de plus, et satisfait donc la gloutonnerie de lafermeture de la seconde partie de l’expression régulière.

Ces règles peuvent également être interprétées au niveau des éléments qui com-posent l’expression régulière. Pour la partie(bl|re) , c’est bienbl qui est misen correspondance, puisque c’est la sous-chaîne correspondante la plus à gauchedansblaireau(règle 1). Une fois cette première correspondance effectuée, la partie[aeiou]+ n’a plus le choix qu’entrea et ai, les deux séquences de voyelles à droitede bl. C’estai qui est mis en correspondance avec[aeiou]+ comme l’indique larègle 2. L’expression régulière complète est par conséquent mise en correspondanceavecblai, concaténation debl et deai.

Bien comprendre ces règles d’association est vital pour la définition des expres-sions régulières. En effet, dans certains cas extrêmes, la partie mise en correspondancepeut varier énormément pour deux expressions apparemment équivalentes.

Prenons comme exemple l’expression/l. * n/ (c’est-à-dire unl suivi d’unnombre quelconque de caractères quelconques puis d’unn) appliquée à la chaînelepetit lapin blanc. La mise en correspondance s’effectue, mais la sous-chaîneconcer-née n’est pas le seul motlapin comme on pourrait éventuellement le souhaiter, maisla sous-chaînele petit lapin blan, c’est-à-dire la sous-chaîne allant du premierl auderniern, afin de satisfaire la gloutonnerie de la sous-expression (. * ), comme indiquéen figure 4.3.

blancle petit lapin

/l.*n/

Figure 4.3. Correspondance entre l’expression/l. * n/ et la chaînele petit lapin blanc

Page 169: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Expressions régulières 177

Un autre exemple significatif est celui de l’expression/(la) * / (soit un nombrequelconque de séquences dela) appliquée à la même chaîne que précédemment. Lapremière règle de correspondance (gauche-droite) indiqueen fait que le premier lieude la chaînele petit lapin blancoù peut s’appliquer l’expression est le début de lachaîne, plus précisément la sous-chaîne de longueur nulle située avant le premier ca-ractère, comme illustré en figure 4.4. Ceci est dû au fait que l’opérateur de ferme-ture (* ) peut correspondre à une séquence nulle, ce qui permet à la règlegauche-droitede s’appliquer de façon triviale.

le petit lapin blanc

/(la)*/

Figure 4.4. Correspondance entre l’expression/(la) * / et la chaînele petit lapin blanc

La définition d’expressions régulières entrant en correspondance avec la bonnesous-chaîne est parfois difficile, notamment lorsque la chaîne visée contient un seg-ment de texte et pas un mot simple. Dans l’exemple précédent,une expression régu-lière entrant en correspondance avec un mot du texte commençant par unl et finissantpar unn est la suivante :/\bl\pL * n\b/ . Cette expression fait appel aux frontièresde mots\b au début et à la fin, afin d’assurer la bonne position des deux lettres auxextrémités du mot, et utilise la classe de caractères prédéfinie \pL qui correspond àtoutes les lettres, excluant donc les séparateurs de mots (espaces, signes de ponctua-tion, etc.), et interdisant ainsi la correspondance avec une sous-chaîne qui couvriraitplusieurs mots du texte. La correspondance se fait au final avec le motlapin, commeindiqué en figure 4.5.

/\bl\pL*n\b/

le petit lapin blanc

Figure 4.5. Correspondance entre l’expression\bl\pL * n\b/ et la chaînele petit lapin blanc

4.5.3. Fermetures non gloutonnes

Une autre possibilité d’adapter plus finement la correspondance est de modifier laseconde règle en utilisant de nouveaux opérateurs de fermeture. Les expressions régu-lières de Perl permettent en effet d’utiliser des fermetures non gloutonnes qui se notentde la façon suivante :* ? pour 0 ou plusieurs occurrences,+? pour 1 ou plusieurs oc-currences et?? pour 0 ou 1 occurrence. Leur syntaxe d’utilisation est exactement la

Page 170: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

178 Perl pour les linguistes

même que les opérateurs gloutons classiques* , + et ?, mais leur fonctionnement leurfait favoriser le minimum de caractères au lieu du maximum.

Par exemple, la correspondance entre l’expression/l. * ?n/ et la chaînele petitlapin blancse fait sur la sous-chaînele petit lapin, c’est-à-dire entre le premierl et lepremiern, comme indiqué en figure 4.6. La première règle de mise en correspondancereste en effet prioritaire.

le petit lapin blanc

/l.*?n/

Figure 4.6. Correspondance entre l’expression/l. * ?n/ et la chaînele petit lapin blanc

4.5.4. Fermetures multiples

Dans le cas où une expression régulière comporte plusieurs fermetures, et notam-ment lorsque ces fermetures sont contiguës et peuvent se chevaucher, le rôle des fer-metures non gloutonnes peut être crucial.

Par exemple, si l’on souhaite définir une expression régulière qui soit en correspon-dance avec une chaîne quelconque commençant par unl, et éventuellement terminéepar uns, l’expression régulière suivante est sans doute celle à laquelle on pense enpremier lieu :/^l. * s?$/ .

Le problème de cette expression est qu’elle comporte deux fermetures compa-tibles. Lorsque la correspondance se fait avec une chaîne qui finit par un s (commelapins), ces final peut être mis en correspondance dans la partie centrale(. * ) aussibien qu’avec les optionnel (s? ). Cette ambiguïté pose des problèmes dans les cas oùl’on utilise une expression régulière pour extraire une sous-chaîne, comme présentéen section 4.6. Lors d’une mise en correspondance de cette expression avec la chaînelapins, le détail de la correspondance est présenté en figure 4.7.

l a p i n s

/^l .* s? $/

Figure 4.7. Correspondance entre l’expression/ˆl. * s?$/ et la chaînele petit lapin blanc

Par contre, si l’on utilise un opérateur non glouton pour la première fermeture,avec l’expression régulière/^l. * ?s?$/ alors les final sera capté par la secondefermeture, comme indiqué en figure 4.8.

Page 171: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Expressions régulières 179

l a p i n s

/^l .*? s? $/

Figure 4.8. Correspondance entre l’expression/ˆl. * ?s?$/ et la chaînele petit lapin blanc

Dans les cas où deux fermetures contiguës sont de gloutonnerie égale, les élémentsqui peuvent avoir plusieurs correspondances sont associés, par défaut, à la fermeturequi est la plus à gauche. Le résultat de l’association seraitdonc le même que celui dela figure 4.7 si les deux opérateurs étaient non gloutons, comme dans l’expression :/^l. * ?s??$/ .

L’utilisation de ces opérateurs de fermeture n’entraîne bien entendu aucune varia-tion de comportement dans la correspondance globale entre une chaîne et une expres-sion régulière. Dans les deux cas précédents, la correspondance avec la chaînelapinsest réalisée. Le comportement des sous-expressions est toutefois, comme nous allonsle voir, très important pour des opérations de manipulationde chaînes, notammentl’extraction de sous-chaînes et la modification de chaînes.

4.6. Extraction de sous-chaînes

Le mécanisme d’association entre une chaîne et une expression se fait, commenous l’avons présenté, pas la mise en correspondance des éléments de l’expressionavec des segments de chaîne, ou sous-chaînes. Dès lors, les expressions régulièrespeuvent être utilisées pour repérer ces sous-chaînes, et les extraire.

Il est par exemple possible, avec une expression régulière,non seulement de testersi une chaîne se termine par uns, mais également de stocker dans une variable la partiede la chaîne qui se trouve avant les final. Pour ce faire, il est nécessaire de faire appelà la notion de mémorisation des expressions régulières.

4.6.1. Mémorisation

Le mécanisme de mémorisation est activé à chaque fois qu’uneexpression régu-lière est utilisée. Son fonctionnement est le suivant : si une ou plusieurs parties del’expression régulière est située entre parenthèses, alors chaque segment de chaînemis en correspondance avec un groupement est disponible dans une variable spéciale.

Le programmeextraire-s.pl(listing 4.2) présente la même structure quetermine-s.pl (listing 4.1), mais permet en plus d’extraire la partie de lachaîne située avant lesfinal le cas échéant.

Page 172: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

180 Perl pour les linguistes

Listing 4.2 – extraire-s.plTest d’une terminaison ens et extraction de sous-chaîne

1 use locale;2 use strict;3

4 print "Entrez un nom : ";5 my $chaine = <STDIN>;6 chomp $chaine;7

8 if ( $chaine =~ /(. * )s$/ ) 9 print "Votre nom se termine par un s\n";

10 print "Si c’est un pluriel régulier, son singulier est ",11 $1,"\n";12 13 else 14 print "Votre nom ne se termine pas par un s\n";15

Ligne de commande :perl extraire-s.pl

Exemple de déroulement :Entrez un nom : lapins

Votre nom se termine par un s

Si c’est un pluriel régulier, son singulier est lapin

L’expression régulière/(. * )s$/ utilisée ici ne change absolument pas la miseen correspondance par rapport à l’expression/s$/ utilisée danstermine-s.pl. En ef-fet, la sous-expression. * n’apporte aucune contrainte supplémentaire. Par contre, lorsde la mise en correspondance, cet élément est associé à la partie de la chaîne d’entréesituée avant les final. Le marqueur de position du début de la ligne n’est pas néces-saire, puisque la gloutonnerie de l’opérateur de fermeturele mettra en correspondanceavec tous les caractères situés avant les.

La variable spéciale qui reçoit cette valeur est ici$1 . Toutes les variables spécialesde ce type ont la même forme, c’est-à-dire un dollar ($) indiquant une variable sca-laire, et un nombre, ici 1. Le nombre correspond simplement au numéro d’ordre dela paire de parenthèses dans l’expression régulière. Puisque l’expression n’a qu’uneseule paire de parenthèses, la variable associée est$1 . Lorsque plusieurs paires deparenthèses sont présentes dans l’expression régulière, les segments correspondantssont associés aux variables$1 pour la première,$2 pour la deuxième, etc. L’ordre estcelui des parenthèses ouvrantes, de gauche à droite.

Le rôle des parenthèses dans une expression régulière est donc double : ellesservent à régler les priorités dans l’interprétation de l’expression, et également à mé-moriser des segments de la chaîne mise en correspondance en affectant les variables

Page 173: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Expressions régulières 181

spéciales. Dans certains cas, ces deux rôles sont présents dans une même expression,comme le montre le programmeradical-able.pl(listing 4.3) qui analyse un adjectif en-ableéventuellement préfixé parin- ou une de ses variantes (ir-, il- ou im-).

Listing 4.3 – radical-able.plExtraction du radical d’un adjectif en-able

1 use locale;2 use strict;3

4 print "Entrez un adjectif en able : ";5 my $chaine = <STDIN>;6 chomp $chaine;7

8 if ( $chaine =~/^((in|ir|il|im)?(. * )able)s?$/ ) 9 print "Vous avez entré l’adjectif : ", $1, "\n";

10 print "Le radical de votre adjectif est : ", $3, "\n";11 12 else 13 print "Votre mot ne se termine pas par able !\n";14

Ligne de commande :perl radical-able.pl

Exemple de déroulement :Entrez un adjectif en able : irrecevables

Vous avez entré l’adjectif : irrecevable

Le radical de votre adjectif est : recev

L’expression régulière utilisée dans ce programme est relativement complexe :/^((in|ir|il|im)?(. * )able)s?$/ . Son équivalent, en éliminant les paren-thèses destinées à la mémorisation, est :/^(in|ir|il|im)?. * ables?$/ . Elleest en correspondance avec toute chaîne commençant éventuellement par une desquatre séquencesin, ir, il ou im, se terminant parable ou ables. Le listage des al-lomorphes du préfixe négatif a seulement pour objet de séparer ce dernier du radical.Les deux paires de parenthèses qui ont été ajoutées permettent de mémoriser l’en-semble de la chaîne sans les final éventuel d’une part, et la partie centrale appariée à. * d’autre part. L’ordre d’ouverture des 3 paires de parenthèses est le suivant :

1) adjectif entier sans les final ;

2) préfixe ;

3) radical.

Il faut noter que la paire de parenthèses entourant les quatre formes possibles dupréfixe entraînent une mémorisation, même si celle-ci n’estpas exploitée dans le pro-gramme. Ce préfixe est disponible dans la variable spéciale$2 .

Page 174: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

182 Perl pour les linguistes

REMARQUE.– A chaque fois qu’une expression régulière est utilisée enPerl, les va-riables spéciales$1 , $2 ... reçoivent automatiquement des valeurs nouvelles. Dès lors,il est nécessaire de les exploiter immédiatement après un test de correspondance parexpression régulière, car leur contenu ne sera plus disponible si l’on utilise une autreexpression régulière dans la suite du programme.

4.6.2. Autres variables spéciales

En plus des sous-chaînes associées aux éléments entre parenthèses, Perl affecte lesvaleurs suivantes à trois variables spéciales supplémentaires :

$& Sous-chaîne en correspondance avec l’intégralité del’expression régulière

$’ (apostrophe) Sous-chaîne située à droite de celle associéeà l’expres-sion régulière

$‘ (apostrophe inverse) Sous-chaîne située à gauche de celle associée à l’expres-sion régulière

Ainsi, lorsque l’expression régulière/\bl\pL * n\b/ est mise en correspon-dance avec la chaînele lapin blanc, ces trois variables reçoivent les valeurs suivantes :

$& vaut lapin$’ vaut blanc$‘ vaut le

Comme pour les variables$1 et suivantes, les valeurs affectées à ces variables nesont disponibles que tant qu’aucune autre expression régulière n’a été utilisée.

4.6.3. Occurrences multiples

Lorsqu’une expression régulière est en correspondance avec des données non for-matées (comme des lignes de texte brut, par opposition à des lignes de lexique oude texte segmenté), il est possible que plusieurs possibilités d’appariement soient en-visageables. La première règle de correspondance indique comme nous l’avons vuque c’est le segment éligible le plus à gauche qui sera retenu. Il est toutefois possibled’itérer l’extraction de sous-chaînes en projetant à nouveau l’expression régulière surla suite de la chaîne. Il faut pour cela :

– remplacer la conditionnelle simpleif par une bouclewhile ;

– utiliser l’optiong lors de la mise en correspondance de l’expression régulière.

Par exemple, le programmeextraction-mots.pl(listing 4.4) affiche, pour une lignede texte en entrée standard, la liste des mots qu’elle contient, numérotés.

Page 175: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Expressions régulières 183

Listing 4.4 – extraction-mots.plExtraction des mots d’une ligne de texte

1 use locale;2 use strict;3

4 print "Entrez une ligne de texte : ";5 my $ligne = <STDIN>;6 chomp $ligne;7

8 my $n;9

10 while ( $ligne =~ /\pL+/g ) 11 $n++;12 print "Mot numéro ", $n, " : ", $&, "\n";13

Ligne de commande :perl extraction-mots.pl

Exemple de déroulement :Entrez une ligne de texte : Le lapin est-il parti ?

Mot numéro 1 : Le

Mot numéro 2 : lapin

Mot numéro 3 : est

Mot numéro 4 : il

Mot numéro 5 : parti

L’expression régulière/\pL+/ est en effet en correspondanceavec toute séquencede lettres. Chaque mot du texte est donc en association avec elle. La répétition de lamise en correspondance permet ainsi d’extraire tous les mots (au sens de séquence delettres) de la ligne de texte. Le tiret et le point d’interrogation final ne sont pas extraits,car ce ne sont pas des lettres.

Ce programme constitue la base de l’opération de segmentation en mots d’un texte,une opération fondamentale dans le traitement de données textuelles. Une versioncomplète d’un programme de segmentation est présentée en annexe A1.

REMARQUE.– Il est possible de cumuler les deux optionsi etg, permettant ainsi unemise en correspondance répétée insensible à la casse. Il suffit simplement de placer cesdeux lettres côte à côte après la deuxième barre oblique (l’ordre n’a pas d’importance),ce qui donne au final :/.../gi ou /.../ig .

4.7. Modification de chaînes par substitution

Le troisième mode d’utilisation des expressions régulières en Perl donne la possi-bilité de modifier une chaîne en y remplaçant des sous-chaînes par d’autres.

Page 176: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

184 Perl pour les linguistes

4.7.1. Principe et syntaxe

Le principe de cette opération est le suivant : on indique à l’aide d’une expressionrégulière la partie de la chaîne qui va être affectée ; puis onprécise par quelle valeurelle doit être remplacée. La syntaxe de cette opération en Perl est la suivante :

$variable =~ s/ expression / chaîne / ;

Par exemple, si la variable$mot contient la chaînelapin, l’instruction suivante :

$mot =~ s/^l/s/ ;

remplacera lel initial par uns, si bien qu’après cette instruction le contenu de$motestsapin. Si la variable$mot ne contient pas de chaîne commençant par unl, ellereste inchangée.

Cette opération s’appuie sur le mode de correspondance entre éléments d’une ex-pression et sous-chaînes tel qu’il est explicité à la section 4.5, notamment en ce quiconcerne les fermetures. C’est la sous-chaîne mise en correspondance avec l’intégra-lité de l’expression régulière qui est remplacée. Ainsi, l’instruction :

$mot =~ s/^l. * /s/ ;

remplacerait maladroitementlapin pars, puisque l’intégralité de la chaîne initiale estmise en correspondance avec l’expression/^l. * / si celle-ci commence par unl.

L’expression régulière peut aussi correspondre à une position dans la chaîne, sielle se limite à un marqueur de position (^ , $ ou \b ). Dans ce cas, la substitution seramène à un simple ajout de caractères. L’instruction suivante, par exemple, ajoute uns à la fin de la chaîne contenue dans la variable$mot 2 :

$mot =~ s/$/s/ ;

La chaîne de remplacement, qui est indiquée entre la deuxième et la troisième barreoblique, est une chaîne classique au sens de Perl. Elle peut comprendre des caractèrescomme la fin de ligne (\n ), la tabulation (\t ), l’espace, etc. Elle peut égalementêtre vide, par exemple lorsque l’on souhaite supprimer une partie de la chaîne parsubstitution. Par exemple, l’instruction suivante supprime un éventuels final dans lavariable$mot :

$mot =~ s/s$// ;

2. Cette instruction est donc strictement équivalente à :$mot = mot . "s" ; .

Page 177: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Expressions régulières 185

Les optionsi etg sont applicables aux instructions de substitution.

L’option i permet ici aussi de s’affranchir des variations de casse lors de la miseen correspondance. Par exemple, l’instruction :

$mot =~ s/^l/s/i ;

changera le contenu de$chaine delapin àsapinmais aussi deLapin àsapin. Il fautnoter que ce sera ici toujours uns minuscule qui sera utilisé comme remplacement.L’option i ne concerne pas la chaîne de remplacement.

L’option g est particulièrement utile puisqu’elle permet un remplacement global,c’est-à-dire qu’elle permet de substituer la chaîne de remplacement indiquée à toutesles sous-chaînes mises en correspondance par l’expressionrégulière. Ainsi, l’instruc-tion suivante permet de remplacertouslesl et lesL de la variable$ligne par dess :

$ligne =~ s/l/s/ig ;

Sans l’optiong, seul le premierl (à gauche) de$ligne serait remplacé par uns. Si par exemple$ligne contient initialement la chaîneLibellule, l’exécution del’instruction :

$ligne =~ s/l/s/gi ;

change cette valeur ensibessuse, alors que celle de :

$ligne =~ s/l/s/i ;

la change ensibellule.

4.7.2. Substitution et mémorisation

Le principe de mémorisation de sous-chaînes est également utilisable dans uneopération de substitution.

Pour utiliser le mécanisme de mémorisation, il suffit d’insérer des parenthèsesdans l’expression régulière et de placer dans la chaîne de remplacement les variablesspéciales correspondantes ($1 , $2 , etc.).

Par exemple, l’instruction suivante intervertit dans le contenu de la variable$ligne deux mots précédés parle et séparés par unet :

$ligne =~ s/le (\pL+) et le (\pL+)/le $2 et le $1/;

Page 178: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

186 Perl pour les linguistes

Ainsi, si $ligne contient la chaînele corbeau et le renard, après substitution ellecontiendrale renard et le corbeau. Il faut noter que les déterminants, même s’ils sontinchangés dans la transformation, doivent être répétés dans la chaîne de remplacement,car ils sont captés par l’expression régulière.

Dans certains cas, la mémorisation est nécessaire pour des transformations pluslimitées. Par exemple, le passage au pluriel d’un nom et de son déterminant défininécessite la mémorisation du nom en question, même si au finalcelui-ci se trouvesimplement suivi d’uns. L’instruction suivante effectue cette transformation :

$ligne =~ /^(le|la) (\pL+)$/les $2s/;

Cette instruction change par exemple la chaînele lapin en les lapins. Notons dansce cas que la chaîne de remplacement$2s signifie que l’on souhaite voir au final laseconde sous-chaîne mémorisée (donc le nom au singulier) suivie d’un s.

4.8. Problématiques avancées

Dans cette partie nous traitons de certaines utilisations plus avancées des ex-pressions régulières. Nous explicitons notamment l’utilisation de variables pour laconstruction d’expressions régulières dans un programme,et nous abordons le conceptde négation de correspondance et les limites de son traitement par les expressions ré-gulières.

4.8.1. Utilisation de variables dans les expressions régulières

Nous avons vu au paragraphe 4.7.2 que l’on pouvait employer des variables spé-ciales de mémorisation dans la chaîne de remplacement lors d’une opération de sub-stitution. Il est bien entendu également possible d’employer des variables scalairestraditionnelles ayant reçu une valeur au préalable.

Mais il est aussi possible d’utiliser des variables scalaires dans lecorps d’uneexpression régulière, et ce quel que soit le contexte d’utilisation de celle-ci (corres-pondance ou substitution).

Dans le cas le plus simple, on peut attribuer à une variable scalaire quelconque unechaîne de caractères qui correspond à une expression régulière complète. Par exemple,si l’on souhaite effectuer un grand nombre d’opérations parexpressions régulièresmettant en jeu des articles, il est possible de définir leur schéma une fois pour toutes,par exemple avec l’affectation suivante :

$articles = "(le|la|les|un|une|des)";

Page 179: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Expressions régulières 187

Par la suite, on peut utiliser cette variable, par exemple pour vérifier qu’une lignede texte (dans la variable$ligne ) contient bien un mot précédé d’un article :

if ( $ligne =~ /$articles \pL+/ ) ...

Dans ce cas, lors de l’interprétation de l’expression régulière, le segment corres-pondant à$articles sera remplacé par le contenu de cette variable et l’expressionrégulière réellement utilisée sera :/(le|la|les|un|une|des) \pL+/ .

Notons que dans ce cas le symbole$ ne signifie plus la fin de ligne, mais est bieninterprété par Perl comme étant la marque d’une variable scalaire. La confusion entreces deux significations est réduite par le fait que la fin de ligne n’est pas censée êtresuivie de quoi que ce soit.

Un problème se pose lorsque l’on fait suivre une telle variable par un caractèrepouvant apparaître dans un identificateur. Par exemple, si l’on définit dans une variableun ensemble de noms, comme par exemple :

$volatile = "(oie|canard|poule|canari)" ;

et que cette variable est utilisée pour rechercher des occurrences de ces chaîneséventuellement suivies d’uns. L’expression régulière correspondante serait la suivante(entre frontières de mots dans notre cas) :

/\b$volatiles?\b/

Le résultat de l’interprétation de cette syntaxe par Perl serait la production d’unmessage d’erreur, indiquant que la variable$volatiles n’est pas définie (si c’estbien le cas et que la variable$volatiles n’existe pas par ailleurs). En effet, lors del’interprétation, Perl va chercher le nom de la variable en utilisant tous les caractèrespossibles à la suite du$, c’est-à-dire toutes les lettres, chiffres ou caractère souligné(_).

Pour éviter ce problème, trois solutions sont envisageables. La première consistesimplement à modifier le contenu de la variable$volatile et à y intégrer lesoptionnel, ou bien à utiliser une seconde variable qui le contiendrait. La deuxièmeconsiste à entourer la variable de parenthèses (c’est-à-dire constituer un groupementréduit à cette seule variable) :/\b($volatile)s?\b/ . La troisième solution, plusdirecte, consiste à entourer les caractères formant le nom de la variable par des acco-lades, bloquant ainsi la mauvaise interprétation de la séquence de lettres. L’expressionrégulière correcte est donc celle-ci :/\b$volatiles?\b/ .

La troisième solution permet de résoudre de la même façon ce problème lorsqu’onutilise des variables dans la chaîne de remplacement d’une instruction de substitution.

Page 180: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

188 Perl pour les linguistes

Une autre situation pouvant nécessiter l’utilisation de variables dans une expres-sion régulière est le cas où un programme interactif demandeà l’utilisateur d’entrerune chaîne de caractères qui va ensuite être recherchée dansune ligne de texte. C’estle cas pour de nombreux programmes d’exploration de donnéeslinguistiques. Dans cecas, la chaîne entrée par l’utilisateur va être stockée dansune variable, puis utilisée entant qu’expression régulière. La partie de programme suivante est un exemple mini-mal, et suppose que la variable$ligne a au préalable reçu comme valeur une lignede texte :

print "Entrez la chaîne recherchée :";

my $recherche = <STDIN>;

chomp $recherche;

...

if ( $ligne =~ /$recherche/ ) ...

On suppose ici que l’utilisateur est conscient que la chaînequ’il entre est utiliséecomme une expression régulière. Il est donc à sa charge de fournir une expressioncorrecte. Mais si tel n’est pas le cas, et que la syntaxe fondamentale des expressionsn’est pas respectée (parenthèses non équilibrées par exemple), un message d’erreursera produit au moment de la mise en correspondance.

En revanche, si la chaîne saisie est, pour le programme commepour l’utilisateur,une chaîne de caractères classique, il est nécessaire de prendre un ensemble de pré-cautions. Le traitement principal consiste à échapper les éventuels métacaractères quise trouvent dans la chaîne$recherche . Par exemple, si l’utilisateur recherche despoints (.) dans le texte et qu’il entre ce caractère tel quel,la réponse du programme neva pas correspondre à sa demande. En effet, dans un contexte d’expression régulière, lepoint sera interprété comme « tout caractère ». L’expression régulière correspondant àla demande de l’utilisateur est en fait :/\./ , le point devant être précédé d’une barreoblique inverse pour perdre son statut de métacaractère. Comme il existe un grandnombre de métacaractères (voir liste au paragraphe A5.8.1), il est nécessaire d’envi-sager un grand nombre d’échappements. Fort heureusement, le langage Perl contientune fonction prédéfinie qui effectue exactement ce travail,nomméequotemeta. Ilsuffit dès lors, dans le cas traité ici, d’appliquer cette fonction à la chaîne entrée parl’utilisateur, de récupérer son résultat dans une seconde variable et d’utiliser celle-cipour la recherche :

print "Entrez la chaîne recherchée :" ;

$recherche = <STDIN>;

chomp $recherche;

$expression = quotemeta($recherche);

...

if ($ligne =~ /$expression/) ...

Page 181: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Expressions régulières 189

4.8.2. Négation et expressions régulières

Pour certaines recherches, extractions ou substitutions,la notion de négation peutêtre très utile dans la définition des chaînes ou segments de chaînes visés. Cette notionlogique fondamentale est toutefois assez délicate à manipuler dans certains cas.

Le cas trivial est celui d’une mise en correspondance où l’oncherche à vérifierqu’une chaîne n’estpas en correspondance globale avec une expression régulière.Il suffit dans ce cas de faire précéder l’expression de comparaison du mot-clénot ,comme dans l’exemple suivant, qui vérifie que la chaîne$mot ne se terminepasparuns :

if (not ($mot =~ /s$/)) ...

Une version plus condensée de la négation est possible, en remplaçant l’opéra-teur =~ par !~ . L’instruction suivante est ainsi strictement équivalente à la versionprécédente :

if ( $mot !~ /s$/ ) ...

La négation est plus complexe lorsqu’elle se combine avec une définition positive.C’est le cas par exemple de la définition d’une expression régulière en correspondanceavec les chaînes commençant pardeet ne finissant pas par uns. L’expression régulière/^de. * [^s]$/ ne définit pas correctement cet ensemble. En effet, la chaîneden’est pas en correspondance avec cette expression régulière, puisqu’elle ne contientpas de caractère après la séquencede, alors que l’expression[^s] correspond à toutcaractère autre ques.

Le problème se pose également lorsque la négation porte sur une séquence decaractères et pas sur un seul. La syntaxe[^] ne concerne que les classes de caractères,et la négation qui y est représentée est limitée.

Par contre, s’il n’est pas possible de définir certains ensembles de chaînes par uneseule expression régulière, il est tout à fait possible de lefaire avec plusieurs expres-sions. Dans le cas précédent, il suffit d’utiliser une conjonction logique qui décomposela double exigence en deux expressions distinctes, par exemple :

if ( ($mot =~ /^de/) and ($mot !~ /s$/) ) ...

Dans des cas encore plus complexes, il peut être nécessaire d’effectuer une extrac-tion, puis de tester par expression régulière la sous-chaîne extraite.

Page 182: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

190

Page 183: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

CHAPITRE 5

Recherche d’unités linguistiques

5.1. Généralités

Les techniques de recherche présentées ici concernent la localisation d’une unitélinguistique (ou d’un ensemble de telles unités) dans une ressource, que celle-ci soitun lexique ou un corpus, annoté ou non. Ce chapitre couvre la recherche d’unités fixes(par exemple un mot particulier) ou d’unités correspondantà un patron de recherche(une terminaison par exemple). La recherche peut être également définie par des cri-tères sur la forme du mot, son lemme et/ou sa catégorie morphosyntaxique quandceux-ci sont disponibles, c’est-à-dire dans des textes étiquetés ou des lexiques mor-phosyntaxiques.

Pour ce chapitre nous utiliserons comme exemple le recueil de nouvellesLesContes de la Bécassede Guy de Maupassant, qui fait partie du corpus de l’ABU(voir paragraphe 1.5.1.4 page 58). Les différents fichiers utilisés ici pour exploiter cedocument sont :

– becass2.txt: le texte non traité (sans entête) ;

– becass2.seg: le texte segmenté (obtenu par le segmenteur présenté en sectionA1.2 page 396 ;

– becass2.tag: le texte catégorisé et lemmatisé parTreeTagger, avec une désam-biguïsation des lemmes (voir paragraphe 1.7.3 page 78).

Ces trois fichiers sont disponibles dans l’environnement detravail.

191

Page 184: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

192 Perl pour les linguistes

5.2. Recherche de mots dans un lexique nu ou un texte segmenté

Qu’il s’agisse d’un lexique simple (sans autre informationdisponible sur ses en-trées que la simple forme des mots) ou d’un texte segmenté (mais non étiqueté), leproblème se ramène à celui du parcours d’un fichier texte comprenant une unité lexi-cale par ligne. Dès lors, la recherche dans cette liste est très simple, la seule variationportant sur le type de mot recherché. Si le mot est connu exactement, on cherche sim-plement à savoir s’il apparaît dans la liste.

5.2.1. Recherche d’un mot exact

Dans cette configuration minimale, l’utilisateur du programme présenté ici donneen entrée un mot et un fichier de texte comprenant un mot par ligne, et reçoit en retourune indication sur la présence ou l’absence de ce mot dans le fichier. Plus précisé-ment, le mot recherché sera indiqué comme paramètre du programme, et les donnéesexaminées seront passées en entrée standard.

Listing 5.1 – recherche-exacte-simple.plRecherche d’un mot exact dans un fichier de texte segmenté ou un lexique simple

1 use strict;2 use locale;3

4 if ( $#ARGV != 0 ) 5 die "Usage :", $0,6 "recherche-exacte-simple.pl mot_recherche\n";7 8

9 my $recherche = $ARGV[0];10 my $trouve = 0;11

12 while ( my $ligne = <STDIN> ) 13 chomp $ligne;14 if ( (lc $ligne) eq (lc $recherche) )15 $trouve = 1;16 last;17 18 19

20 if ( $trouve ) 21 print "Le mot \"", $recherche, "\" apparaît dans l’entrée\n ";22 23 else 24 print "Le mot \"", $recherche,25 "\" n’apparaît pas dans l’entrée\n";26

Ligne de commande :perl recherche-exacte-simple.pl mot < fichier_texte

Page 185: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Recherche d’unités linguistiques 193

Exemple :perl recherche-exacte-simple.pl baron < becass2.seg

Résultat :Le mot "baron" apparaît dans l’entrée

Détails du programme :

Les lignes 4 à 7 correspondent à l’arrêt du programme (avec indication d’un mes-sage d’erreur) si l’utilisateur a fourni autre chose qu’un seul argument (donc si letableau@ARGVcontient autre chose qu’un seul élément), voir section 3.9 page 155.Si la ligne de commande est correcte, le mot recherché est disponible dans la variable$recherche .

Le but de ce programme étant de vérifier simplement la présence ou l’absence dumot, il n’est pas nécessaire de parcourir l’ensemble des lignes de l’entrée standard. Aucontraire, dès que le mot a été trouvé, le programme s’arrêtesans analyser le reste desdonnées.

La boucle définie dans ce programme (lignes 12 à 18) parcourt l’entrée standardligne par ligne de façon classique, et chaque ligne est comparée au mot recherché.

La comparaison se fait indépendamment des variations de casse, en appliquantau mot recherché ($recherche ) et au mot examiné ($ligne ) la fonction lc, quirenvoie la version en minuscules de la chaîne qu’elle reçoiten paramètre. Ainsi, lacomparaison s’effectue entre les versions minuscules des deux chaînes, si bien queBaronet baronseront considérés comme identiques. Cette fonction ne modifie pas lecontenu de la variable à laquelle elle s’applique, son résultat n’est utilisé que pour lacomparaison. Le résultat aurait été identique en utilisantla fonction inverse,uc quiproduit la version en majuscules d’une chaîne.

Si la comparaison donne un résultat positif, deux actions sont exécutées :

– la variable$trouve est affectée avec la valeur 1 : cette variable permettra deconnaître, en fin de programme, le résultat de la recherche ;

– la bouclewhile s’arrête grâce à l’instructionlast. Cette instruction met immé-diatement fin à la boucle dans laquelle elle se trouve1, quel que soit le type de boucle(for , foreach ou comme iciwhile. Dans le cas présenté ici,last fait en sorte que lesprochaines lignes de l’entrée ne soient pas examinées. Le programme passe dans cecas aux instructions situées après la boucle (lignes 20 à 26).

1. Si plusieurs boucles sont imbriquées, seule la boucle la plus interne est concernée.

Page 186: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

194 Perl pour les linguistes

La bouclewhile va donc se terminer d’une des deux façons suivantes :

– si le mot a été trouvé, la boucle a été interrompue par l’instruction last et lavariable$trouve vaut 1 ;

– si le mot n’a pas été trouvé, la bouclewhile s’est déroulée jusqu’à la fin deslignes de l’entrée standard, et la variable$trouve a gardé sa valeur initiale de 0.

Les instructions conditionnelles des lignes 20 à 26 permettent ainsi d’afficher unmessage final correspondant à une de ces deux situations, en testant directement lavaleur de vérité correspondant à la variable$trouve .

COMMENTAIRE.– Un objectif similaire à une telle recherche peut être de compter lenombre d’occurrences du mot recherché ; un tel programme ne s’applique bien en-tendu qu’à un texte segmenté dans lequel un mot est susceptible d’être répété. Deuxmodifications sont nécessaires :

– la boucle principale doit parcourir l’ensemble de l’entrée standard, ce qui rendinutile l’utilisation de la variable$trouve et exclut l’emploi delast ;

– lors du repérage d’une occurrence du mot recherché, il fautaugmenter de 1une variable scalaire initialisée à zéro (par exemple$compteur ++ ). Cette variable$compteur correspond donc au nombre d’occurrences du mot cherché, et sa valeursera affichée en fin de programme.

Pour plus de détails sur le calcul des fréquences, voir le chapitre 6.

5.2.2. Recherche exacte d’une liste de mots

Il arrive généralement que l’on recherche non pas un seul motmais une liste. Ondispose dans ce cas d’un fichier contenant la liste des mots recherchés (un mot parligne), en plus de la ressource dans laquelle ces mots serontcherchés (lexique ou textesegmenté). Le programme suivant (recherche-exacte-liste.pl) prend en paramètre unnom de fichier contenant une liste de mots à rechercher dans l’entrée standard :

Listing 5.2 – recherche-exacte-liste.plRecherche d’une liste de mots dans un fichier de texte segmenté ou un lexique

1 use strict;2 use locale;3

4 my (@liste, %recherche, %trouve);5

6 if ( $#ARGV != 0 ) 7 die "Usage : ", $0, " fichier_liste \n";8 9

10 my $fichier = $ARGV[0];

Page 187: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Recherche d’unités linguistiques 195

11

12 open ( LISTE, "<", $fichier ) or die13 "Impossible d’ouvrir", $fichier ," : ", $!, "\n";14

15 while ( my $ligne = <LISTE> ) 16 chomp $ligne;17 push ( @liste, (lc $ligne) );18 $recherche (lc $ligne) = 1;19 20 close LISTE;21

22 while ( my $ligne = <STDIN> ) 23 chomp $ligne;24 if ( defined ( $recherche (lc $ligne) ) ) 25 $trouve$ligne = 1;26 27 28

29 foreach my $ligne ( @liste ) 30 print "Le mot \"$ligne\" ";31 if ( defined ( $trouve$ligne ) ) 32 print "apparaît\n";33 34 else 35 print "n’apparaît pas\n";36 37

Ligne de commande :perl recherche-exacte-liste.pl fichier_liste < fichier_texte

Exemple :perl recherche-exacte-liste.pl couleurs.txt < becass2.s eg

Où le fichiercouleurs.txt contient les mots suivants :blanc

blanche

blanches

blancs

bleu

bleue

bleues

bleus

Résultat :Le mot "blanc" apparaît

Le mot "blanche" apparaît

Le mot "blanches" apparaît

Le mot "blancs" apparaît

Le mot "bleu" apparaît

Page 188: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

196 Perl pour les linguistes

Le mot "bleue" n’apparaît pas

Le mot "bleues" n’apparaît pas

Le mot "bleus" apparaît

Détails du programme :

Ce programme se décompose en trois parties : une lecture du fichier contenant lesmots à rechercher (lignes 10 à 20), puis la recherche proprement dite (lignes 22 à 27),et enfin l’affichage des résultats (lignes 29 à 37).

Pour la première, on utilise le descripteurLISTE pour ouvrir le fichier dont lenom est donné en paramètre. Les mots qui composent cette liste (chacun sur uneligne) sont ensuite stockés à la fois dans le tableau@liste , puis comme clés duhachage%recherche . En effet, pour la recherche, il est beaucoup plus efficace dedisposer d’un hachage, puisque cette structure permet de savoir immédiatement (sanspasser par une boucle) si un mot examiné en est une clé ou non (voir paragraphe 3.8.1page 148). Le tableau@liste ne sert qu’à l’affichage final des résultats, pour mémo-riser l’ensemble des mots recherchés dans l’ordre où ils apparaissaient dans le fichier.En effet, un désavantage majeur d’un hachage est qu’il ne permet pas de préserverl’ordre des éléments (clés) qui y sont stockés, contrairement à un tableau. Le hachage%recherche est utilisé en associant aux clés des valeurs arbitraires (ici elles valenttoujours1).

Pour la deuxième partie, l’entrée standard est parcourue ligne par ligne (donc motpar mot), et pour chaque mot du texte (ou plutôt sa version en minuscules) on vérifiesimplement s’il est défini comme clé du hachage%recherche . Si c’est le cas, onle stocke comme clé du second hachage%trouve en utilisant le même principe queprécédemment, c’est-à-dire en lui attribuant une valeur arbitraire (1). Si plusieurs oc-currences d’un mot cherché sont rencontrées, la valeur associée restera égale à 1, sansajouter de nouvelles clés.

Pour la troisième partie, l’affichage des résultats se fait en parcourant la liste desmots recherchés (@liste ) et en indiquant pour chacune d’eux s’il a été trouvé (doncs’il est aussi une clé de%trouve ).

Le type d’affichage présenté ici est bien entendu modulable en fonction des be-soins. Il suffit d’adapter les blocs de l’instruction conditionnelle de la dernière bouclepour, par exemple, n’afficher que les mots trouvés, ou au contraire les mots qui n’ap-paraissent pas.

5.2.3. Recherche par expressions régulières

La recherche dans un lexique nu ou un texte segmenté des occurrences d’un ouplusieurs schémas exprimés par des expressions régulières(voir chapitre 4) ne diffère

Page 189: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Recherche d’unités linguistiques 197

pas beaucoup d’une recherche exacte. Les différences reposent bien entendu sur lemode de comparaison, mais aussi sur le fait que le résultat d’une telle recherche n’estplus simplement une question de présence ou d’absence, maisbien l’identification desmots trouvés, puisque ceux-ci ne sont pas connus exactement.

Le programmerecherche-expreg-simple.plreçoit en paramètre une expression ré-gulière, et affiche en sortie les lignes (mots) de l’entrée standard qui ont été mises encorrespondance avec cette expression, dans l’ordre du texte.

Listing 5.3 – recherche-expreg-simple.plRecherche par expression régulière dans une liste de mots

1 use strict;2 use locale;3

4

5 if ( $#ARGV != 0 ) 6 die "Usage : ", $0, " expression\n";7 8

9 my $expression = $ARGV[0];10 while ( my $ligne = <STDIN> ) 11 chomp $ligne;12 if ( $ligne =~ /$expression/i ) 13 print $ligne, "\n";14 15

Ligne de commande :perl recherche-expreg-simple.pl expression < fichier_texte

Exemple :perl recherche-expreg-simple.pl "ités?$" < becass2.seg

Cette commande permet de rechercher les mots se terminant par la chaîneité ouités dansLes Contes de la Bécasse.

Résultat (extrait) :invités

déshérités

brutalité

autorité

vérité

fatuité

agité

obscurité

...

Page 190: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

198 Perl pour les linguistes

Détails du programme :

L’expression régulière est le seul paramètre du programme,et est stockée dans$expression . La comparaison s’effectue pour chaque ligne du flux d’entrée stan-dard, en ignorant les différences de casse lors de la comparaison, grâce à l’optioni :il n’est plus nécessaire ici d’appliquer la fonctionlc à la chaîne examinée.

Si le mot stocké sur une ligne est en correspondance avec l’expression régulière, ilva être simplement affiché en sortie standard.

COMMENTAIRE.– Dans le cas où l’utilisateur donne une expression régulière erronée,Perl indiquera une erreur comme si celle-ci avait été tapée dans le programme, etarrêtera immédiatement l’exécution. Dans un programme plus complexe, cela peutposer des problèmes, si l’expression régulière n’est utilisée que lorsque le programmea déjà effectué des calculs, puisque ceux-ci seront alors perdus. Pour vérifier la validitéd’une expression régulière donnée en paramètre, les lignesde codes suivantes doiventêtre placées immédiatement après l’affectation de la variable$expression :

eval "test" =~ /$expression/;

if ($@ ne "")

die "Erreur dans l’expression régulière : ", $@,"\n";

La fonctioneval permet au programme d’évaluer une partie de code variable. Sicette partie de code n’est pas correcte, alors la variable spéciale$@recevra commevaleur le message d’erreur renvoyé par l’interpréteur Perl, mais le programme nes’arrêtera pas pour autant. Ce code permet donc de tester l’expression régulière (àl’aide d’une comparaison avec une chaîne arbitraire, ici"test" ) et, le cas échéant,d’émettre un message d’erreur avant d’arrêter le programme. Le contenu de la variable$@est également affiché.

Exemple erroné :perl recherche-expreg-simple.pl "ités(" < becass2.seg

Résultat :Erreur dans l’expression régulière : Unmatched ( in regex;

marked by <-- HERE in m/ités( <-- HERE $/ at

recherche-expreg-simple.pl line 14, <STDIN> line 1.

Le message d’erreur, quoique complexe, indique précisément le problème de syn-taxe de l’expression régulière : ici une parenthèse ouvrante n’est pas fermée.

Les erreurs ainsi repérées sont toutefois limitées à la seule syntaxe des expressionsrégulières : des expressions n’ayant aucun sens mais syntaxiquement correctes seront

Page 191: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Recherche d’unités linguistiques 199

utilisées normalement par un tel programme (comme/$ité/ , qui indique que lachaîneité doit se trouveraprèsla fin de ligne, et donc ne renverra aucun résultat).

REMARQUE.– Cette méthode ne sera pas utilisée systématiquement dansles pro-grammes utilisant des expressions régulières présentés par la suite. En effet, la com-plexité ajoutée par cette vérification ne se justifie que pourdes programmes de grandetaille ou destinés à être exécutés par des utilisateurs moins expérimentés qui néces-sitent une explication claire des erreurs commises.

5.2.4. Recherche par expressions régulières avec tri des résultats

Il est bien souvent utile de présenter le résultat d’une recherche par expressionsrégulières entriant les mots ainsi obtenus dans l’ordre lexicographique (plutôt quedans l’ordre d’apparition dans le texte). Ce mode de présentation permet notammentde mieux repérer les familles morphologiques (en regroupant les mots débutant par lesmêmes séquences de caractères), et de faire apparaître plusfacilement les répétitions.Afin d’obtenir une liste triée des mots correspondant à une expression régulière, il estnécessaire d’apporter un ensemble de modifications au programmerecherche-expreg-simple.pl, qui sont présentées dansrecherche-expreg-tri.pl.

Listing 5.4 – recherche-expreg-tri.plRecherche par expression régulière dans une liste de mots, avec tri des résultats

1 use strict;2 use locale;3

4 if ( $#ARGV != 0 ) 5 die "Usage : ", $0, " expression\n";6 7

8 my $expression = $ARGV[0];9 my @resultats;

10 while ( my $ligne = <STDIN> ) 11 chomp $ligne;12 if ( $ligne =~ /$expression/i ) 13 push ( @resultats, $ligne );14 15 16

17 my @resultats_tries = sort @resultats;18 print join ( "\n" , @resultats_tries ),"\n";

Ligne de commande :perl recherche-expreg-tri.pl expression < fichier_texte

Exemple :perl recherche-expreg-tri.pl "ités?$" < becass2.seg

Page 192: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

200 Perl pour les linguistes

Cette commande permet de rechercher les mots se terminant par la chaîneité ouités dansLes Contes de la Bécasse.

Résultat (extrait) :agité

agité

autorité

autorité

brutalité

brutalités

charité

cité

crédulités

...

Comme on peut le voir, le tri lexicographique permet d’identifier rapidement larépétition deagité et d’autorité (qui apparaissent chacun deux fois dans le texte),ainsi que l’utilisation debrutalitéau singulier et au pluriel.

Détails du programme :

Ce programme reprend en grande partie le fonctionnement derecherche-expreg-simple.pl.

La première différence repose sur l’utilisation d’un tableau (@resultats ) pourstocker les mots repérés au lieu de les afficher au fur et à mesure. L’opération de trine peut en effet s’effectuer qu’une fois l’ensemble des motsrecherchés connu. Lacommandepush permet d’ajouter au fur et à mesure les mots repérés dans le tableau.

La syntaxe depush est la suivante :

push( tableau , valeur )

A la suite de cette instruction,tableau contient une nouvelle cellule, dont lecontenu estvaleur . La taille du tableau a donc été augmentée de 1. Il est égalementpossible, avecpush, d’ajouter plusieurs valeurs à un tableau en une seule instruction,voire d’ajouter à un tableau l’ensemble des éléments d’un autre. Pour ce faire cas, ilsuffit d’indiquer les valeurs à ajouter séparées par des virgules, ou d’utiliser un tableauen deuxième argument.

A la fin de la boucle de parcours des données,@resultats contient donc l’en-semble des mots du texte correspondant à l’expression régulière dans l’ordre d’ap-parition dans le texte (son affichage à ce moment donnerait lemême résultat querecherche-expreg-simple.pl). Pour obtenir le type de présentation visé, son contenu

Page 193: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Recherche d’unités linguistiques 201

va d’abord être trié par ordre lexicographique, puis affiché. Ces deux opérations fontchacune appel à une fonction spécifique.

Le tri lexicographique est effectué par la fonctionsort , appliquée au tableau@resultats . Il est possible de configurersort pour préciser le critère de tri, maispar défaut c’est l’ordre lexicographique qui est utilisé. Il est important de noter quela fonction sort ne modifie pas le tableau sur lequel elle s’applique, mais renvoiecomme résultat un nouveau tableau. Ce nouveau tableau est stocké dans la variable@resultats_tries .

REMARQUE.– L’ordre lexicographique utilisé parsort respecte la logique des lettresaccentuées du français grâce à la localisation indiquée en tête du programme (uselocale; ). Voir l’annexe A3 pour plus de détails.

Le tableau trié va ensuite être affiché, un élément par ligne.Pour ce faire, au lieud’utiliser une boucle sur l’ensemble des éléments de@resultats_tries , la fonc-tion join est utilisée. Cette fonction permet en effet de construire une chaîne de ca-ractères en concaténant tous les éléments du tableau qui luiest donné en paramètreen les séparant par une chaîne fixe, elle aussi donnée en paramètre. Sa syntaxe est lasuivante :

join( chaîne , tableau )

Ainsi, l’instruction :

join ("\n", @resultats_tries)

construit une chaîne contenant tous les éléments de@resultats_triesséparés par desretours à la ligne ("\n" ). Le résultat, une longue chaîne courant sur plusieurs lignes,est ensuite simplement affiché. Comme le dernier élément du tableau n’est pas suivid’une fin de ligne après application dejoin , un dernier caractère de fin de ligne estaffiché.

5.3. Recherche de mots dans un texte étiqueté

Dans le cas de ressources enrichies, telles que des textes étiquetés et/ou lemmati-sés, la recherche d’unités lexicales peut utiliser des informations plus étendues que lasimple forme de surface des mots.

Les textes étiquetés (voir paragraphe 1.7.3, page 78) organisent les différentes in-formations associées à un mot en autant de colonnes, les différents champs d’uneligne étant séparés par des tabulations (ou un autre caractère n’apparaissant pas dansles données elles-mêmes). L’essentiel du travail nécessaire à leur exploitation reposedonc sur le découpage de ces données, afin d’appliquer les comparaisons aux bonnesinformations.

Page 194: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

202 Perl pour les linguistes

5.3.1. Recherche par lemme ou catégorie dans un texte étiqueté

Une recherche courante dans un texte étiqueté consiste en l’extraction d’uni-tés lexicales dont on fixe le lemme ou la catégorie. Par exemple, on peut souhaiterconnaître la liste des formes fléchies d’un verbe (dont on va simplement préciser l’in-finitif), ou bien l’ensemble des adverbes contenus dans le texte.

Dans les deux cas, cette recherche va réaliser l’affichage des formes, alors que larecherche va se baser sur les lemmes ou les catégories des occurrences.

Le programmerecherche-lemme.plrecherche dans un texte étiqueté l’ensembledes formes correspondant à un lemme donné en paramètre :

Listing 5.5 – recherche-lemme.plRecherche par lemme dans un texte étiqueté

1 use strict;2 use locale;3

4 if ( $#ARGV != 1 ) 5 die "Usage : ", $0, " lemme répertoire\n";6 7

8 my $lemme = $ARGV[0];9

10 while ( my $ligne = <STDIN> )11 chomp $ligne;12 my @t = split ( /\t/, $ligne );13

14 if ( $t[2] eq $lemme ) 15 print $t[0], "\n";16 17

Ligne de commande :perl recherche-lemme.pl lemme < texte_étiqueté

Exemple :perl recherche-lemme.pl boire < becass2.tag

Résultat (extrait) :buvaient

bu

boire

boire

but

bu

buvait

Page 195: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Recherche d’unités linguistiques 203

Détails du programme :

Une ligne d’un fichier de texte étiqueté est composée de troischaînes, dans l’ordre :

– la forme de surface du mot ;

– l’étiquette correspondant à sa catégorie morphosyntaxique;

– son lemme.

Ces trois chaînes étant séparées par des tabulations. La tabulation étant un caractèredifficile à manipuler au clavier, on utilise pour la représenter la notation\t , que cesoit dans les chaînes constantes ou dans les expressions régulières.

Voici un rappel des premières lignes du fichierbecass2.tag :Le DET:ART le

vieux ADJ vieux

baron NOM baron

des PRP:det du

Ravots NOM ravot

Le programme analyse chaque ligne du fichier afin d’en extraire les trois sous-parties, avant d’effectuer la comparaison sur le lemme (troisième colonne), et éven-tuellement d’afficher la forme correspondante (première colonne). Il existe plusieursfaçons d’analyser les lignes d’un texte étiqueté pour en extraire ces différentes infor-mations.

La première consiste à utiliser une expression régulière qui mémorise les différentséléments, de la façon suivante :

if ($ligne =~ /(. * )\t(. * )\t(. * )/) ...

L’expression régulière s’appuie sur les tabulations pour identifier les trois sous-chaînes qu’elles séparent. Comme il n’y a que deux tabulations sur une même ligne,la mise en correspondance se fait correctement. Par la suite, les trois éléments de laligne sont mémorisés, et disponibles dans les variables suivantes :

– la forme dans$1 ;

– la catégorie dans$2 ;

– le lemme dans$3 .

La seconde façon, plus compacte, fait appel à la fonctionsplit. Cette fonction apour rôle de découper une chaîne de caractères en utilisant une expression régulièrepour indiquer les points de section. Le résultat obtenu est un tableau de chaînes. Lasyntaxe complète est la suivante :

split(/ expression /, chaîne )

Page 196: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

204 Perl pour les linguistes

Le fonctionnement précis desplit est le suivant :

– l’expression régulièreexpression est recherchée danschaîne partout oùelle peut s’appliquer : les endroits où elle s’applique sontles points de section. Laméthode utilisée par Perl pour repérer ces points est similaire à celle utilisée pour lacorrespondance globale d’une expression régulière, voir paragraphe 4.2.1 page 164 ;

– chaque sous-chaîne dechaîne située entre deux points de section est extraiteet forme un élément du tableau résultant ;

– la chaîne située entre le début dechaîne et le premier point de section constituele premier élément du tableau,même sielle est vide) ;

– la chaîne située entre le dernier point de section et la fin dechaîne constitue ledernier élément du tableau,sauf sielle est vide).

Dansrecherche-lemme.pll’instruction :

my @t = split (/\t/, $ligne);

applique donc ce principe à une ligne du texte étiqueté ($ligne ). Les points de sec-tion sont ici les tabulations (\t ), et le résultat est stocké dans le tableau@t.

Le tableau@t est donc reconstruit à chaque ligne, et contient dans l’ordre lestrois chaînes correspondant à la forme ($t[0] ), à la catégorie ($t[1] ) et au lemme($t[2] ).

La comparaison se fait ensuite entre le lemme recherché et letroisième élément dutableau ($t[2] ). Si le lemme correspond, il suffit alors d’afficher la forme,stockéedans la première case du tableau ($t[0] ).

COMMENTAIRES.– La comparaison se fait ici directement, sans passer par les formesminuscules. La raison en est qu’un lemme est systématiquement écrit en minuscule ensortie d’un analyseur morphosyntaxique, sauf pour les nomspropres.

Les formes sont présentées dans l’ordre naturel du texte, aufur et à mesure deleur découverte par le programme. Il est tout à fait possible, comme on l’a vu dansles programmes précédents, de les présenter triées par ordre lexicographique (voirparagraphe 5.2.4).

Pour baser une recherche sur la catégorie morphosyntaxiqueau lieu du lemme, ilsuffit simplement de changer le numéro de la colonne sur laquelle se fait la compa-raison, donc, en utilisant une variable nommée$categorie au lieu de$lemme, deremplacer la ligne :

if ($t[2] eq $lemme) par :

if ($t[1] eq $categorie)

Page 197: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Recherche d’unités linguistiques 205

Adaptation à d’autres formats : les programmes présentés dans cet ouvrageconcernent les sorties de l’étiqueteur TreeTagger (voir paragraphe 1.7.3 page 78).D’autres étiqueteurs peuvent produire en sortie des résultats similaires, mais sous unautre format, différant de celui de TreeTagger par la natureet l’ordre des éléments, ouencore par le caractère de séparation. L’utilisation d’un découpage parsplit permetd’adapter aisément le programme.

D’autres ressources, notamment les lexiques, ont également un format similaire,et les techniques pour les analyser sont proches de celles présentées ici. Le chapitre 8présente plus en détails l’exploitation des lexiques.

5.3.2. Recherche multicritère par expressions régulières

La recherche par le lemme ou la catégorie seulement ne peut toutefois suffire à untravail sur les unités lexicales. Il est courant que l’on aità combiner des contraintes,ce qui entraîne la nécessité d’une recherche multicritère,par exemple lorsque l’oncherche les adjectifs en-abledans un texte. Ce type de recherche implique générale-ment des recherches par motifs, et non plus des recherches exactes, nous aborderonsdonc directement le cas de critères définis par des expressions régulières.

Pour ce type de recherche, il est souvent plus rapide d’écrire directement une ex-pression régulière qui effectue à la fois la recherche et l’extraction de la forme. Leprogramme a alors une taille fort réduite, mais n’est pas directement réutilisable.

5.3.2.1.Recherche des adjectifs en-abledans un texte étiqueté

Si l’on prend le cas des adjectifs en-able, le programme suivant les extrait direc-tement d’un texte étiqueté en entrée standard :

Listing 5.6 – adjectifs-able.plExtraction des adjectifs en-abled’un texte étiqueté

1 use strict;2 use locale;3

4 while ( my $ligne = <STDIN> ) 5 chomp $ligne;6 if ( $ligne =~ /(. * )\tADJ\t. * able$/ ) 7 print $1, "\n";8 9

Ligne de commande :perl adjectifs-able.pl < texte_étiqueté

Page 198: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

206 Perl pour les linguistes

Exemple :perl adjectifs-able.pl < becass2.tag

Résultat (10 premières lignes) :aimable

invraisemblables

incomparable

convenable

inévitable

excusable

adorable

agréable

misérable

lamentables

Détails du programme :

L’essentiel du travail effectué repose donc sur l’expression régulière, dont le fonc-tionnement est le suivant :

– elle repère les mots dont l’étiquette estADJ, comprise entre deux tabulations(\tADJ\t ). Puisqu’une ligne de texte étiqueté ne comporte que deux tabulations, iln’y a pas d’ambiguïté sur la colonne qui est mise en correspondance;

– elle repère également les mots dont le lemme se termine enable, ou plus préci-sément les lignes se terminant parable ( able$ ). Elle contient également une partiequi sera mise en correspondance avec la partie initiale du lemme (. * ) ;

– elle mémorise également la forme du mot, c’est-à-dire tousles caractères situésavant la première tabulation. C’est cette partie initiale qui est affichée si le mot est misen correspondance avec l’expression entière, auquel cas laforme est accessible dansla variable$1 , puisque la partie de l’expression correspondant à la formeest situéeentre la première (et unique) paire de parenthèses.

Adaptation :

Voici à titre d’exemples une liste d’expressions régulières destinées à être misesen correspondance avec les lignes d’un texte étiqueté :

Expression Définition Résultat^(anti[^\t] * )\t Mots dont la forme commence paranti Forme dans$1^([^\t] * s)\t Forme des mots se terminant par uns Forme dans$1^(.)\tPUN\t Signes de ponctuation Forme dans$1\tVER. * \t(. * er)$ Verbes dont l’infinitif se termine parer Lemme dans$1\t(KON|PRP)\t(. * ) Conjonctions ou prépositions Lemme dans$2

Page 199: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Recherche d’unités linguistiques 207

5.3.2.2.Recherche générique

Si l’on souhaite rendre ce type de recherche générique, il faut utiliser un pro-gramme avec deux expressions régulières comme paramètres :la première correspon-dant à la catégorie, et la seconde au lemme. C’est ce que fait le programmerecherche-categorie-lemme.pl:

Listing 5.7 – recherche-categorie-lemme.plRecherche dans un texte étiqueté sur la catégorie et le lemme

1 use strict;2 use locale;3

4 if ($#ARGV != 1) 5 die "Usage : ", $0,6 " expression_categorie expression_lemme\n";7 8

9 my $categorie = $ARGV[0];10 my $lemme = $ARGV[1];11

12 while ( my $ligne = <STDIN> ) 13 chomp $ligne;14 if ( $ligne =~ /(. * )\t$categorie\t$lemme/ ) 15 print $1, "\n";16 17

Ligne de commande :perl recherche-categorie-lemme.pl expression_categorieexpression_lemme < texte_étiqueté

Exemple :perl recherche-categorie-lemme.pl "ADJ" ". * able$" < becass2.tag

Résultat : le même que précédemment pour les adjectifs en-able.

Détails du programme :

Le fonctionnement de ce programme est identique à l’exempleprécédent(adjectifs-able.pl), à la différence que les critères de recherche sont passés enpara-mètres et ne sont plus des constantes. L’expression régulière utilisée pour la compa-raison est donc basée sur les deux sous-chaînes$categorie et $lemme.

Le fonctionnement efficace de ce programme repose donc entièrement sur les ex-pressions passées en paramètres par l’utilisateur. Ce dernier devra notamment bienfaire attention à définir les deux expressions de façon complète, en y intégrant notam-ment des sous-schémas de type. * à gauche et en les terminant par$ s’il recherche

Page 200: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

208 Perl pour les linguistes

une terminaison. Il est bien sûr possible de mettre en place un garde-fou pour prévenirl’utilisateur en cas d’expressions mal formées, comme il a été montré au paragraphe5.2.3.

5.3.3. Critères de recherche plus complexes

Pour certaines recherches, une expression régulière, aussi complexe soit-elle, nepeut suffire à exprimer les critères nécessaires. C’est notamment le cas de la négation,qui ne peut être représentée aisément par ce formalisme dansle cas général. Il n’estpas simple, par exemple, de rechercher les adjectifs-ablequi ne sont paspréfixés pardé-ni in-.

Pour ce genre de recherche, la solution la plus directe consiste à définir une ex-pression utilisant des connecteurs logiques. Cette approche nécessite généralement undécoupage des différents champs de chaque ligne. Le programme suivant recherchedans un texte étiqueté les adjectifs en-able non préfixés pardé- ni in- ou ses allo-morphes (il- , ir- et im-).

Listing 5.8 – adjectifs-able-non-prefixes.plRecherche dans un texte étiqueté des adjectifs en-ablenon préfixés pardé-ni in-

1 use strict;2 use locale;3

4 while ( my $ligne = <STDIN> ) 5 chomp $ligne;6

7 my @t = split ( /\t/, $ligne);8 if ( ($t[1] eq "ADJ") and9 ($t[2] =~ /able$/) and

10 ($t[2] !~/^(dé|in|im|il|ir)/) ) 11 print $t[0],"\n";12 13

Ligne de commande :perl adjectifs-able-non-prefixes.pl < texte_étiqueté

Exemple :perl adjectifs-able-non-prefixes.pl < becass2.tag

Résultat (10 premières lignes) :aimable

convenable

excusable

Page 201: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Recherche d’unités linguistiques 209

adorable

agréable

misérable

lamentables

abominable

épouvantables

formidable

REMARQUE.– Comme prévu les adjectifsinvraisemblables, incomparableet inévi-tablene font plus partie de la liste produite par ce programme.

Détails du programme :

Ce programme utilise la même procédure de découpage des lignes avecsplit quecelle présentée dans le listing 5.5. L’expression booléenne de recherche est quant àelle la conjonction de trois conditions :

– la catégorie ($t[1] ) doit êtreADJ ;

– le lemme ($t[2] ) doit se terminer parable ;

– le lemme ne doitpascommencer pardé , in , im , il ou ir .

5.4. Recherche de mots ou de séquences de mots dans un texte brut

Lorsque la recherche s’applique à un texte brut et non plus à un texte segmentédeux différences principales sont à prendre en compte :

– les frontières de mots ne sont plus explicites, il est alorsnécessaire de les prendreen compte par des expressions régulières plus complexes ;

– une même ligne de texte peut contenir plusieurs occurrences du mot recherché ;

– il devient possible, par une expression régulière, de rechercher des séquences demots et non plus seulement des mots seuls.

5.4.1. Recherche d’un mot

La recherche d’un seul mot dans un texte brut revient à définirune expression régu-lière correspondant à ce mot. Toutefois, il convient de bienenvisager le contexte danslequel ce mot peut apparaître, et d’éviter d’obtenir de fausses correspondances avecune chaîne qui contiendrait une séquence de caractères équivalentes. Par exemple,une recherche naïve du motavecpeut très bien aboutir à une correspondance avecle motclavecin. La meilleure façon de restreindre ce type de fausses occurrences estd’utiliser dans l’expression régulière des frontières de mots (\b , voir paragraphe 4.3.3page 172). Ainsi, l’expression régulière/\bavec\b/ évite la correspondance avecclavecin.

Page 202: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

210 Perl pour les linguistes

D’autre part, il est tout à fait possible que plusieurs mots répondant aux mêmescritères apparaissent sur la même ligne de texte. Si l’on n’yremédie pas, un pro-gramme utilisant simplement une expression régulière ne renverra que le premiermot de chaque ligne qui y correspond. Le programmerecherche-able-texte-brut.plrecherche dans un texte brut les mots se terminant parableouables:

Listing 5.9 – recherche-able-texte-brut.plRecherche des mots finissant parableouablesdans un texte brut

1 use strict;2 use locale;3

4 while ( my $ligne = <STDIN> ) 5 chomp $ligne;6

7 while ( $ligne =~ /\pL * ables?\b/g ) 8 print $&, "\n";9

10

Ligne de commande :perl recherche-able-texte-brut.pl < fichier_texte

Exemple :perl recherche-able-texte-brut.pl < extrait-becass2.tx t

où le fichierextrait-becass2.txtcontient le passage suivant (sur une seule ligne) :

Je traversais les grandes dunes au sud de Ouargla. C’est là undes plus étranges pays du monde. Vous connaissez le sable uni ,le sable droit des interminables plages de l’Océan.

Résultat :sable

sable

interminables

REMARQUE.– Les deux occurrences desable, bien que situées sur la même ligne, sontretrouvées par le programme.

Détails du programme :

La recherche effectuée par ce programme se décline suivant une double boucle. Laboucle principale parcourt l’entrée standard ligne par ligne suivant le schéma habituel.

Page 203: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Recherche d’unités linguistiques 211

Pour chaque ligne, une boucle va rechercher les occurrencesdes mots se terminant enableou ablesen utilisant une recherche globale. La recherche globale, mise en placepar l’optiong va en effet permettre de répéter la recherche dans le cas où plusieursoccurrences sont présentes sur une même ligne. Son mécanisme est explicité au para-graphe 4.6.3 (page 182).

L’expression régulière (/\pL * ables?\b/ ) se décompose comme suit :

– le mot lui-même ne doit comprendre que des lettres, et aucunautre caractère :on utilise donc la catégorie\pL pour exprimer les lettres, et non pas le point (. ) tropgénérique. La gloutonnerie de la fermeture* garantit de plus quetoutesles lettres dumot seront concernées par la correspondance;

– la séquenceable (ou ables) doit se trouver obligatoirement à la fin du mot, etnon dans sa partie médiane, pour que la correspondance se fasse : l’expression utilisedonc la notion de frontière de mot (\b ) après la séquence finale ;

– quand une correspondance se fait, la sous-chaîne mise en correspondance cor-respond au mot recherché, et est disponible dans la variablespéciale$&.

Une frontière de mot en début d’expression est superflue, puisque la contrainte neporte que sur la terminaison. Toutefois, un\b en début d’expression n’altérerait enrien son comportement.

Il est important de noter que la définition formelle d’un mot utilisée dans ce pro-gramme est une séquence delettres maximale. Ce programme ne permet donc pasd’extraire en l’état l’intégralité d’un mot composé, puisque le tiret n’est pas une lettre.Il est toutefois possible d’étendre sa couverture en autorisant explicitement le tiret, ceque fait l’expression régulière suivante :

/[\pL\-] * ables?\b/

5.4.2. Recherche d’une séquence simple de mots

On appelle ici séquencesimplede mots une séquence courte de taille fixe nonsusceptible de recouvrement. Les séquences complexes sontexposées au paragraphe5.4.3.

La recherche en texte brut d’une séquence de mots ne pose qu’un seul problèmesupplémentaire par rapport à la recherche d’un seul mot. Il concerne les fins de lignesqui, dans un texte brut, sont simplement un artefact dû à la mise en page. De ce fait, unerecherche par expression régulière peut très bien se révéler faussement infructueuse sila séquence cherchée est située dans le texte sur plusieurs lignes.

Par exemple, la figure 5.1 présente un extrait de la licence dedistribution de l’ABU(voir paragraphe 1.5.1.4 page 58), telle qu’on la trouve dans les entêtes des fichiers

Page 204: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

212 Perl pour les linguistes

distribués par cette association. Les fins de lignes visibles dans l’extrait sont celles quel’on trouve dans le fichier (de même que les fautes d’orthographe et d’accentuation).

1. Toute copie à des fins privées, à des fins d’illustration d e

l’enseignement ou de recherche scientifique est autorisée .

2. Toute diffusion ou inclusion dans une autre oeuvre doit

a) soit inclure la presente licence s’appliquant a l’ensemb le de la

diffusion ou de l’oeuvre dérivee.

b) soit permettre aux bénéficiaires de cette diffusion ou de cette

oeuvre dérivée d’en extraire facilement et gratuitement un e

version numérisée de chaque texte inclu, muni de la présente

licence. Cette possibilité doit être mentionnée explicite ment et

de façon claire, ainsi que le fait que la présente notice

s’applique aux documents extraits.

Figure 5.1. Extrait de la licence ABU

La recherche dans ce texte de la séquence «la diffusion» doit donc aboutir, mêmesi elle est répartie sur deux lignes dans l’alinéaa). Une analyse ligne par ligne dufichier de texte ne peut permettre cela : il est donc nécessaire d’effectuer la rechercheparagraphe par paragraphe.

Le programmerecherche-det-X.plrecherche dans un texte brut toutes les sé-quences composées d’un article défini (le, la, les, l’) suivi d’un mot.

Listing 5.10 – recherche-det-X.plRecherche en texte brut d’une séquence composée d’un article défini suivi d’un motquelconque

1 use strict;2 use locale;3

4 $/="\n\n";5

6 while ( my $paragraphe = <STDIN> )7 $paragraphe =~ s/\n/ /g;8 $paragraphe =~ s/ +/ /g;9

10 while ( $paragraphe =~ /\b(le |la |les |l\’ ?)(\pL+)/g ) 11 print $&,"\n";12 13

Page 205: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Recherche d’unités linguistiques 213

Ligne de commande :perl recherche-det-X.pl < fichier_texte

Exemple :perl recherche-det-X.pl < licence-ABU.txt

où le fichierlicence-ABU.txtcontient le texte présenté en figure 5.1.

Résultat :l’enseignement

la presente

l’ensemble

la diffusion

l’oeuvre

la présente

le fait

la présente

REMARQUE.– Le traitement proposé ici suppose que le texte est correctement séparéen paragraphes par des lignes vides.

Détails du programme :

Contrairement aux programmes précédents, la lecture des données d’entrée ne sefait plus ligne par ligne mais paragraphe par paragraphe. Ladéfinition formelle d’unparagraphe est ici un ensemble de lignes séparé par une lignevide (ou plus préci-sément deux caractères de fin de ligne consécutifs). Pour effectuer cette lecture, il estnécessaire de modifier une variable spéciale de Perl : le séparateur de flux d’entrée. Ceséparateur, défini dans la variable$/ a comme valeur par défaut le caractère de fin deligne (\n ). Le découpage en paragraphes nous conduit donc à redéfinir cette variableen lui attribuant comme valeur la chaîne\n\n correspondant à deux fins de lignesconsécutives. Une fois cette valeur modifiée, les opérations de lecture se font norma-lement, mais la chaîne renvoyée par chaque opération de lecture suit le découpageindiqué.

Comme les chaînes stockées tour à tour dans la variable$paragraphe ne cor-respondent plus à des lignes mais à des suites de lignes, des modifications sont né-cessaires avant leur exploitation. Notamment, il est nécessaire de supprimer tous lescaractères de fin de ligne dans le paragraphe analysé en les remplaçant par des es-paces (ligne 7). Les espaces ainsi ajoutés évitent le collage des mots séparés par unefin de ligne. De plus, le type de texte traité est également susceptible de contenir desséquences de caractères d’espace à des fins de mise en page (notamment pour simulerune marge gauche). Toutefois, ces espaces excédentaires peuvent compliquer la re-cherche de la séquence, c’est pourquoi il est préférable de remplacer une séquence deplus de deux espaces par un seul (ligne 8).

Page 206: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

214 Perl pour les linguistes

Une fois le paragraphe normalisé, la recherche s’y fait classiquement par uneexpression régulière en recherche globale, comme dansrecherche-able-texte-brut.pl.L’expression indique que la séquence cherchée est composéed’un article défini (parmiles quatre formes possibles), suivi d’un mot unique. Les deux mots sont séparés obli-gatoirement par un espace (et un seul) pour les trois premières formes d’article, maispas pour la forme élidée (l’ ). Toutefois, il est prudent de prévoir un tel espace dans cedernier cas, afin d’adapter le programme à une typographie incorrecte.

COMMENTAIRES.– Dans le cas où le texte n’est pas correctement segmenté enparagraphes, ou s’il n’y a pas de ligne vide les séparant, il ne faut pas hésiter pource type de recherche à stocker l’intégralité du texte à traiter dans une seule chaînede caractères. Ceci se fait simplement en affectant à la variable$/ la chaîne vide.Dans ce cas, il n’est plus nécessaire de mettre en place une boucle pour lire le fichier,puisque l’intégralité de son contenu est lu en une seule fois. Le code correspondantest donc le suivant :

$/ = "";

my $texte = <STDIN>;

$texte =~ s/\n/ /g;

$texte =~ s/ +/ /g;

while ($texte =~ /\b(le |la |les |l\’ ?)(\pL+)/g)

print $&, "\n";

Ce type de traitement est à effectuer avec précaution, surtout pour les donnéesvolumineuses, puisque l’ensemble du texte est stocké en mémoire.

5.4.3. Recherche de séquences complexes

Les séquences complexes sont celles qui sont susceptibles de recouvrement,comme c’est le cas pour certaines structures syntaxiques. Par exemple, les séquencesde typeX de X, lorsqu’elles sont projetées sur des structures du typeX1 de X2 de X3

doivent conduire au repérage de deux occurrences :X1 de X2 etX2 de X3. L’approcheutilisée pour les séquences simples ne permet d’extraire que la première de ces deuxoccurrences.

Pour remédier à cette lacune, il est donc nécessaire de procéder à une progressionplus précise dans le paragraphe. Le programmerecherche-X-de-X.plpermet d’ex-traire toutes les séquences du typeX de X et X de Det X.

Page 207: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Recherche d’unités linguistiques 215

Listing 5.11 – recherche-X-de-X.plRecherche de séquences du typeX de X etX de Det X dans un texte brut

1 use strict;2 use locale;3

4 $/="\n\n";5

6 while ( my $paragraphe = <STDIN> )7 $paragraphe =~ s/\n/ /g;8 $paragraphe =~ s/ +/ /g;9

10 while ( $paragraphe =~11 /\pL+ (de |d’ ?|du )(le |la |les |l’ ?)?(\pL+)/ ) 12 print $&, "\n";13 $paragraphe = $3.$’;14 15

Ligne de commande :perl recherche-X-de-X.pl < fichier_texte

Exemple :perl recherche-X-de-X.pl < licence-ABU.txt

où licence-ABU.txta le contenu indiqué en figure 5.1.

Résultat :fins d’illustration

illustration de l’enseignement

ou de recherche

ensemble de la diffusion

ou de l’oeuvre

bénéficiaires de cette

ou de cette

dérivée d’en

numérisée de chaque

muni de la présente

et de façon

REMARQUE.– Les deux premières séquences extraites correspondent bien à deuxstructures en chevauchement, le texte initial étantà des fins d’illustration de l’en-seignement.

Détails du programme :

La structure générale de ce programme correspond à celle derecherche-det-X.pl,notamment pour la lecture par paragraphes. L’expression régulière comprend quatreparties :

Page 208: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

216 Perl pour les linguistes

– le repérage du premier mot (X) suivi d’un espace :\pL+ ;

– la prépositionde ou du, ou bien la forme élidéed’ (qui peut ne pas être suivied’un espace) :(de |d’ ?|du ) ;

– un éventuel article défini :(le |la |les |l’ ?)? ;

– le second mot de la séquence :(\pL+) .

La gestion des occurrences multiples est toutefois différente de celle du pro-gramme précédent, du fait que deux séquences peuvent se chevaucher. Pour cela, iln’est pas possible d’utiliser le mode de recherche global des expressions régulières,puisque dans ce cas la recherche se poursuitaprèsl’occurrence. Il est donc nécessairede gérer précisément la partie de la chaîne sur laquelle va sereprojeter l’expressionrégulière une fois une première occurrence repérée. Ceci sefait en modifiant au furet à mesure le contenu de la variable$paragraphe . Après une correspondance, lapoursuite de la recherche doit en effet se faire sur la partiede chaîne située à droite decelle repérée (contenue dans$’ ), à laquelle est ajouté par concaténation à gauche lesecond terme de l’expression (contenu dans$3).

Voici le détail de ce mécanisme pour la chaîne suivante, stockée dans la variable$paragraphe :

A des fins d’illustration de l’enseignement ou de recherche...

A l’issue de la première correspondance, les différentes variables ont le contenusuivant :

– $& vautfins d’illustration ;

– $3 vautillustration ;

– $’ vaut de l’enseignement ou de recherche...

$paragraphe va donc prendre comme valeurillustration de l’enseignement oude recherche.... Cette nouvelle valeur va être utilisée pour repérer l’occurrence sui-vante, qui va bien permettre d’extraireillustration de l’enseignement, et ainsi de suite.

COMMENTAIRES.– Ce type de mécanisme est à mettre en place à chaque fois qu’untel chevauchement peut se présenter entre deux séquences recherchées.

Il est par contre plus simple d’extraire des séquences de ce type de longueur va-riable (du typeX de X de X de X...), lorsque l’on cherche à obtenir les séquencesde longueur maximale. Il suffit dans ce cas de définir une expression régulière danslaquelle la séquencede X est répétée grâce à l’opérateur de fermeture. Ceci se fait enutilisant l’expression suivante :

/\pL+( (de |d’ ?|du )(le |la |les |l’ ?)?(\pL+))+/

Page 209: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Recherche d’unités linguistiques 217

A ce stade, comme il apparaît clairement au vu des résultats de ce programme,l’absence d’information sur la nature des mots dans un textebrut entraîne le repéragede séquences de toutes sortes, et pas nécessairement des séquences de typeN de N(commeou de recherche). Pour affiner ce type de recherche, il est nécessaire d’utiliserun texte étiqueté.

5.5. Recherche de séquences de mots dans un texte étiqueté

Le repérage de syntagmes ou d’autres structures syntaxiques passe en premièreapproximation par celui de séquences de mots, chacun de ces mots étant défini parun ou plusieurs critères. Dans un texte étiqueté, il est en effet possible de s’appuyersur les lemmes et/ou les catégories morphosyntaxiques des mots qui le composent,comme cela a été présenté à la section 5.3 (page 201). Toutefois, la lecture ligne parligne (c’est-à-dire mot par mot) ne permet pas de manipuler des séquences, puisqu’iln’y a pas dans une telle boucle de mémorisation des données précédentes.

Il existe deux approches distinctes pour effectuer ce type de recherche. La pre-mière, plus simple, est limitée à des séquences dont la longueur est fixe.

5.5.1. Recherche de séquences de longueur fixe

Cette première solution passe par une représentation en mémoire de l’ensembledes données à manipuler : formes, lemmes et catégories des mots du texte, tout enrespectant leur ordre naturel.

Les séquences de longueur fixe que l’on va traiter ici sont du type N de N ousimilaires. Le programme suivant les extrait d’un texte étiqueté :

Listing 5.12 – recherche-N-de-N.plRecherche de séquencesN de Ndans un texte étiqueté

1 use strict;2 use locale;3

4 my ( @formes, @categories, @lemmes );5

6 while ( my $ligne = <STDIN> )7 chomp $ligne;8

9 my @t = split ( /\t/, $ligne );10 push ( @formes, $t[0] );11 push ( @categories, $t[1] );12 push ( @lemmes, $t[2] );13 14

15 for ( my $i = 0 ; $i <= ($#formes - 2) ; $i++ )

Page 210: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

218 Perl pour les linguistes

16 if ( ($categories[$i] eq "NOM") and17 ( ($lemmes[$i+1] eq "de") or ($lemmes[$i+1] eq "du") ) and18 ($categories[$i+2] eq "NOM") ) 19

20 print $formes[$i], " ", $formes[$i+1], " ",21 $formes[$i+2], "\n";22 23

Ligne de commande :perl recherche-N-de-N.pl < texte_étiqueté

Exemple :perl recherche-N-de-N.pl < becass2.tag

Résultats (10 premières lignes) :baron des Ravots

roi des chasseurs

paralysie des jambes

reste du temps

homme de commerce

juge d’ instruction

jours de soleil

pigeon de temps

moment des chasses

coups de fusil

REMARQUE.– La séquencepigeon de tempscorrespond au passage suivant :... lâ-chait un pigeon de temps en temps...Pour éviter ce type de résultat, il serait nécessaired’effectuer un repérage des expressions adverbiales dans le cadre d’une analyse syn-taxique complexe.

Détails du programme :

La structure de données utilisée dans ce programme pour stocker l’ensemble desdonnées contenues dans le texte étiqueté est basée sur des tableaux. Plus précisément,trois tableaux sont utilisés, un pour chaque champ associé aux mots du texte (forme,catégorie et lemme). Les trois tableaux obtenus sont ditsparallèles, en ce sens queles informations situées à la case numéron de chacun de ces tableaux concernent lemême mot.

La phase de lecture du texte (bouclewhile) concerne donc uniquement le remplis-sage des trois tableaux parallèles. La méthode utilisée pour analyser chaque ligne eten extraire les trois chaînes de caractères est basée sursplit et un tableau temporaire@t, comme expliqué au paragraphe 5.3.1. Ce premier découpage des lignes du texte

Page 211: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Recherche d’unités linguistiques 219

étiqueté en tableaux permet notamment une plus grande facilité d’expression et ungain de temps de calcul pour la recherche des séquences.

La recherche à proprement parler s’effectue dans la bouclefor , qui parcourt avecl’index $i les numéros de cellules des trois tableaux. On se base ici de façon arbi-traire sur la taille du tableau@formes , mais les trois tableaux ont de toute façon lamême taille. L’arrêt de la boucle pour une valeur de($#formes - 2) , correspon-dant à l’antépénultième mot du texte est dû au fait que la séquence recherchée est delongueur 3, et qu’elle ne peut donc débuter par aucun des deuxderniers mots.

Chaque passage dans la bouclefor correspond à l’examen de la présence d’uneséquenceN de N commençant à la position$i . L’expression logique se décomposede la façon suivante :

– le mot n°$i doit être un nom ;

– le mot suivant (numéro$i+1 ) doit être une des flexions possibles de la préposi-tion de ou de l’article contractédu ;

– le troisième mot (numéro$i+2 ) doit aussi être un nom.

Si ces trois conditions sont remplies, alors la séquence estaffichée, en utilisant lesformes de surface des mots de numéros$i à$i+2 .

COMMENTAIRES.– Le chevauchement possible entre deux séquences de typeN de Nest ici bien pris en compte, puisqu’à chaque passage dans la boucle de recherche, laséquence est recherchée en se décalant d’un seul mot.

Par contre, la recherche de séquences maximales est autrement plus complexe avecce type de programmes, puisqu’elle nécessite la mise en place d’un automate à étatsfinis.

5.5.2. Recherche de séquences par automates à états finis

Un automate à états finis est un formalisme très couramment utilisé dans la ma-nipulation de données linguistiques. Il permet de définir formellement des séquencesd’unités apparaissant dans un flux, et constitue en même temps une méthode pour lesreconnaître. Le principe d’un automate à états finis est le suivant :

– il est composé d’un ensemble fini d’étatscorrespondant aux différents stades dela reconnaissance d’une séquence. Il comprend notamment unétat initial (correspon-dant à la situation par défaut, quand aucun élément de la séquence n’a été identifié) etun état final (quand une séquence complète a été identifiée). Achaque moment de sonfonctionnement, l’automate est dans un de sesétats;

– on peut définir entre deux états unetransition, qui indique, en fonction des unitésrencontrées dans le flux analysé, que l’automate doit passerd’un état à un autre ;

Page 212: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

220 Perl pour les linguistes

– l’automate analyse une unité (mot) à la fois. En fonction del’état dans lequel ilse trouve, et en fonction des transitions définies, il modifieou non l’état dans lequel ilse trouve ;

– lorsqu’il atteint son état final, la séquence correspondante a été trouvée ;

– lorsque l’unité analysée ne permet pas de suivre une transition, l’automate serepositionne dans son état initial.

Les automates à états finis se représentent très naturellement sous la forme degraphes, dans lesquels les état sont représentés par des nœuds numérotés, et les tran-sitions par des arcs orientés reliant ces nœuds.

Nous prendrons comme exemple un automate à états finis capable de reconnaîtreles séquences du typeN de (DET) N de (DET) N...aussi longues que possible. Plusprécisément, les séquences visées comprennent :N

N de N

N de DET N

N de N de N

etc.

La représentation graphique de l’automate est donnée en figure 5.2. On y voit quequatre états suffisent à définir ce type de séquence, l’état 0 étant l’état initial, et l’état1 étant l’état final (indiqué par un double cercle). Tous les chemins (ou successions detransitions) partant de l’état 0 vers l’état 1 correspondent à un séquence de typeN de(DET) N de (DET) N...Cet automate définit en quelque sorte, comme une expressionrégulière, une infinité de possibilités de telles séquences2.

0

NOM

NOM

NOM

de

DET

1 2

3

Figure 5.2. Automate à états finis pour la reconnaissance de séquences detypeN de (DET) N de (DET) N...

2. Les expressions régulières et les automates à états finis sont d’ailleurs très proches, les pre-mières n’étant au bout du compte qu’une notation particulière d’un sous-ensemble des seconds.

Page 213: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Recherche d’unités linguistiques 221

Prenons comme exemple de fonctionnement l’analyse de la séquence correspon-dant au texte :Une paralysie des jambes le clouait à son fauteuil. On détaillera éga-lement comment doit se comporter l’automate en termes d’affichage des séquencesrepérées.

L’analyse se déroule comme suit :

– initialisation de l’automate qui est placé en état initial(0) ;

– état 0, mot analyséUne : c’est un déterminant, aucune transition n’est possibleà partir de l’état actuel, l’automate reste dans son état initial ;

– état 0, mot analyséparalysie: c’est un nom, l’automate passe en état 1 ;

– état 1, mot analysédes: c’est une forme dede, l’automate passe en état 2 ;

– état 2, mot analyséjambes: c’est un nom, l’automate passe en état 1 ;

– état 1, mot analyséle : c’est un pronom, aucune transition n’est possible à partirde l’état actuel, l’automate revient dans son état initial (0) ;

– état 0, mot analyséclouait : c’est un verbe, l’automate reste dans son état initial,etc.

Le fonctionnement de l’automate est donc relativement simple pour la reconnais-sance des structures visées, une fois son schéma défini.

Il est par contre nécessaire d’ajouter un ensemble de traitements associés aux tran-sitions pour permettre l’affichage des formes correspondantes. A chaque fois que l’au-tomate arrive dans l’état final (1), une séquence candidate aété repérée. Elle n’esttoutefois pas maximale tant que l’automate peut encore effectuer des transitions. Dansl’exemple ci-dessus, ce n’est que lorsque le motle est analysé, et que l’automate re-vient dans son état initial que la séquenceUne paralysie des jambespeut être affichée.

Le programmeautomate-N-de-N.plpermet de reconnaître et d’afficher en sortietoutes les séquences maximales de ce type se trouvant dans untexte étiqueté fourni enentrée standard.

Listing 5.13 – automate-N-de-N.plRecherche de séquencesN de (DET) N de (DET) N...par automate à états finis dansun texte étiqueté

1 use strict;2 use locale;3

4 my $etat = 0;5 my @sequence = ();6 my @final = ();7 while ( my $ligne = <STDIN> )8 chomp $ligne;9 my ( $forme, $categorie, $lemme ) = split ( /\t/, $ligne );

Page 214: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

222 Perl pour les linguistes

10

11 if ( ($etat == 0) and ($categorie eq "NOM") )12 push (@sequence, $forme);13 $etat = 1;14 @final = @sequence;15 16 elsif ( ($etat == 1) and17 ( ($lemme eq "du") or ($lemme eq "de") ) )18 push (@sequence, $forme);19 $etat = 2;20 21 elsif ( ($etat == 2) and ($categorie eq "NOM") )22 push (@sequence, $forme);23 $etat = 1;24 @final = @sequence;25 26 elsif ( ($etat == 2) and ($categorie =~ /^(DET|PRO:DEM)/) )27 push (@sequence, $forme);28 $etat = 3;29 30 elsif ( ($etat == 3) and ($categorie eq "NOM") )31 push (@sequence, $forme);32 $etat = 1;33 @final = @sequence;34 35 else 36 if ( $etat > 0 )37 print join (" ", @final), "\n";38 39 @sequence = ();40 $etat = 0;41 42

Ligne de commande :perl automate-N-de-N.pl < texte_étiqueté

Exemple :perl automate-N-de-N.pl < becass2.tag

Résultats (10 premières lignes) :baron des Ravots

ans

roi des chasseurs de sa province

années

paralysie des jambes

fauteuil

pigeons de la fenêtre de son salon

perron

reste du temps

homme de commerce

Page 215: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Recherche d’unités linguistiques 223

Détails du programme :

L’approche par automates à états finis ne nécessite pas que l’ensemble des don-nées contenues soient accessibles dans des tableaux, puisqu’un automate analyse leséléments un à un dans leur ordre naturel. Une simple boucle delecture ligne par lignedu fichier étiqueté est donc suffisante.

L’analyse de chaque ligne se fait ici encorevia la fonctionsplit en s’appuyant surles tabulations. Toutefois, l’extraction des trois champs(forme, catégorie et lemme)se fait de façon légèrement différente. La variante employée ici en ligne 8 s’appuiesur le fait qu’il est possible de recopier directement un tableau (fourni parsplit) versun tableau dont les éléments sont représentés par des variables scalaires. Cette étape,plus compacte, est équivalente à la décomposition suivante:

my @t = split (/\t/, $ligne);my $forme = $t[0];my $categorie = $t[1];my $lemme = $t[2];

Le mot décrit sur chaque ligne va ensuite être analysé par l’automate. Pour ce faire,un ensemble de conditionnelles exclusives (reliées parelsif) correspondent chacune àune transition de l’automate. Ces transitions sont définiespar un état de départ (indi-qué par la variable$etat ) et une condition sur la nature du mot analysé (qui portesur sa catégorie3 ou sur son lemme en fonction des cas). La dernière clause de lastruc-ture conditionnelle (exprimée parelse) correspond aux cas où aucune des transitionsexplicitées dans l’automate n’est possible, et que celui-ci doit donc revenir dans sonétat initial.

L’action principale réalisée lors de chaque transition estla modification de l’étatde l’automate, en affectant la variable$etat avec la valeur correspondant à l’étatd’arrivée de la transition. Les autres actions réalisées correspondent à la mise en placede l’affichage des séquences reconnues. Pour ce faire, il estnécessaire de gérer deuxtableaux :

– @sequence, qui contient la liste de tous les mots qui ont permis une transition ;

– @final , qui contient la liste de tous les mots qui ont permis une transitionjusqu’à l’état final.

La distinction entre ces deux tableaux est nécessaire si l’automate ne peut effectuerune transition alors qu’il est dans l’état 2 ou 3. C’est par exemple la situation qui

3. La détection d’un déterminant se fait par une expression régulière car les étiquettes deTreeTagger pour les déterminantes sont du type :DET:ART (article), DET:POS (possessif),PRO:DEM(démonstratif). Voir paragraphe 1.7.3 page 79 pour plus de détails.

Page 216: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

224 Perl pour les linguistes

se présente dans l’analyse d’un segment commesous prétexte de renouveler.... Lenomprétextepermet de passer à l’état 1, et la prépositionde en état 2. Par contre, laprésence d’un verbe (renouveler) entraîne le retour en état initial de l’automate. Danscette situation, la séquence la plus longue rencontrée jusqu’ici est prétexte, et non pasprétexte de.

Du point de vue du programme, le tableau@sequence stocke au fur et à me-sure tous les mots (formes de surface) rencontrés lors d’unetransition quelconque. Achaque passage dans l’état 1, son contenu est recopié dans@final . Lorsque l’au-tomate revient dans son état initial (clauseelsede la conditionnelle), c’est donc soncontenu qui est affiché. Rien n’est affiché si l’automate se trouvait déjà dans son étatinitial (et donc qu’aucun nom n’a été rencontré), ce qui explique la dernière condition-nelle qui vérifie que le numéro de l’état actuel est strictement supérieur à0.

Ce type d’automate peut très facilement être enrichi, par exemple en autorisantdes adjectifs avant ou après les noms. Le mécanisme mis en place permet au final dereconnaître des séquences très complexes. La seule difficulté ici est la construction del’automate ; le programme correspondant est une simple énumération des transitionssous la forme de conditions comme indiqué dans le programme donné en exemple.

5.6. Recherche dans un ensemble de fichiers

Indépendamment de la nature de l’unité recherchée, et du type de données danslesquelles la recherche s’effectue, il n’est pas rare d’avoir à étendre la recherche à unensemble de fichiers au lieu de la limiter à un seul. Le cas le plus fréquent est celui oùles données examinées constituent un corpus stocké dans uneliste de fichiers.

Nous présenterons ici la méthode à utiliser pour répondre à ce genre de situa-tion, qui peut être adaptée à chacun des types de recherche présentés dans ce cha-pitre. Comme exemple, nous reprendrons le cas de la recherche d’un lemme dansun texte étiqueté, présenté dans le programmerecherche-lemme.pl(listing 5.5, para-graphe 5.3.1).

Le programmerecherche-lemme-fichiers.plpermet donc de rechercher un lemme(donné en argument) dans tous les fichiers contenant un texteétiqueté présents dansun répertoire (lui aussi donné en argument). Les fichiers à traiter sont repérés par leprogramme en fonction de leur extension (ici le programme netraite que les fichiersse terminant par.tag ).

Page 217: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Recherche d’unités linguistiques 225

Listing 5.14 – recherche-lemme-fichiers.plRecherche d’un lemme dans un ensemble de textes étiquetés

1 use strict;2 use locale;3

4 if ( $#ARGV != 1 ) 5 die "Usage : ", $0, " lemme répertoire\n";6 7

8 my $lemme = $ARGV[0];9 my $repertoire = $ARGV[1];

10

11 opendir ( REP, $repertoire ) or12 die "Impossible d’ouvrir ", $repertoire, " : ", $!, "\n";13 my @fichiers = readdir( REP );14 closedir ( REP );15

16 my @fichierstag = grep (/\.tag$/, @fichiers);17

18 foreach my $fichier ( sort @fichierstag ) 19 open ( FIC, "<", $repertoire."/".$fichier) or20 warn "Erreur d’ouverture de ",$fichier, " :" ,$!, "\n";21

22 while ( my $ligne = <FIC> )23 chomp $ligne;24 my @t = split ( /\t/, $ligne );25

26 if ( $t[2] eq $lemme ) 27 print $t[0], "\t", $fichier,"\n";28 29 30 close ( FIC );31

Ligne de commande :perl recherche-lemme-fichiers.pl lemme répertoire

Exemple :perl recherche-lemme-fichiers.pl dépêtrer C:\PPL\Corpu s\ABU

Cette ligne de commande est destinée au système Windows. La version adaptéeau système Unix peut être obtenue en remplaçant dans les chemins les barres obliquesarrières (\) par des barres obliques avant (/) et en modifiantla localisation du répertoirePPL (~/PPL). Ici, le chemin du corpusABU devient~/PPL/Corpus/ABU.

Résultat :dépêtrée germinie3.tag

dépêtre historiettes2.tag

dépêtrer historiettes2.tag

dépêtra lettresjuives231.tag

dépêtrer nddp1.tag

dépêtrer ren05101.tag

Page 218: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

226 Perl pour les linguistes

REMARQUE.– L’exemple ci-dessus entraîne l’analyse de tous le corpusABU distri-bué avec l’environnement de travail, soit plus de 250 fichiers et l’examen de plus de13 millions de mots. Son exécution peut donc, suivant les cas, nécessiter plusieursminutes de calcul.

Détails du programme :

Une fois obtenus le lemme et le nom du répertoire où sont stockés les fichiers detexte étiquetés, la première opération spécifique à ce programme est de calculer la listedes fichiers à analyser.

Cette opération se fait en quatre étapes :

– ouverture du répertoire viala fonctionopendir (lignes 11 et 12) : cette opérationest très similaire à celle réalisée paropensur un fichier. On utilise un descripteur derépertoire (iciREP) pour représenter de façon interne le répertoire en question. Undescripteur de répertoire fonctionne exactement comme un descripteur de fichier : ilse note en majuscules et n’a pas besoin d’être déclaré. Commepour les ouvertures defichiers, il est nécessaire de prévoir l’échec de l’ouverture d’un répertoire, en utilisantla syntaxeor die à la suite deopendir pour les cas où le répertoire indiqué n’existepas ou est indisponible ;

– lecture du répertoire viala fonctionreaddir (ligne 13). Cette fonction renvoiesimplement, pour un descripteur de répertoire donné, la liste complète des noms defichiers et de sous-répertoires qui s’y trouvent. Cette liste est ici stockée dans le tableau@fichiers ;

– fermeture du répertoire viala fonctionclosedir (ligne 14). Cette fonction estanalogue àclosepour un fichier, et indique que la lecture du répertoire est terminée ;

– sélection des fichiers en fonction de leur extension(ligne 16). Le tableau@fichiers contient l’ensemble des noms des fichiers contenus dans le répertoirecible. Comme le traitement ne doit s’appliquer qu’aux seulsfichiers contenant un texteétiqueté, on ne retient que ceux dont le nom se termine par l’extension.tag . Cettesélection se fait ici simplement en utilisant la fonctiongrep pour filtrer le tableau. Lafonctiongrep a la syntaxe suivante :grep (/ expression régulière /, tableau )et renvoie un nouveau tableau qui contient les seuls éléments detableau qui sonten correspondance avec l’expression régulière. Dans le casprésenté ici, le tableau@fichierstag contient donc au final les noms de fichiers se terminant par.tagqui se trouvent dans le répertoire cible.

Une fois la liste des noms de fichiers obtenue, il est possiblede la parcourir, etd’analyser un par un chacun de ces fichiers. La boucleforeachdes lignes 18 à 31 vase décomposer comme suit :

– ouverture du fichiercorrespondant en utilisant la fonctionopenet le descripteurde fichierFIC . Toutefois, la liste@fichiers ne contient que lesnomsdes fichiers,

Page 219: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Recherche d’unités linguistiques 227

et pas leur chemin complet. Le paramètre communiqué à la fonctionopenest donc unechaîne composée de trois éléments : le chemin du répertoire où le fichier se trouve, unséparateur (/ )4 et le nom du fichier à analyser. A la différence des programmesvusprécédemment, l’échec de l’ouverture d’un fichier ne doit pas ici entraîner l’arrêt duprogramme : ce n’est donc pas la fonctiondie qui est utilisée, maiswarn. Cette fonc-tion permet simplement d’afficher un message d’erreur (sur le flux standard d’erreur)afin de prévenir l’utilisateur qu’un fichier n’a pu être analysé, mais sans compromettrepour autant la suite des analyses ;

– analyse du fichier, ligne par ligne, de la même façon que dans le programmerecherche-lemme.pl. Toutefois, à la différence de ce dernier, lorsqu’une occurrencedu lemme cherché a été trouvée, le nom du fichier qui la contient est affiché en plusde la forme du mot correspondant ;

– fermeture du fichier. Comme pour chaque utilisation d’un fichier, sa fermetureest nécessaire une fois le traitement effectué. Cette étapepermet également delibérerle descripteurFIC qui va servir, au prochain passage dans le boucle, à manipuler unnouveau fichier.

4. Le séparateur utilisé dans les chemins de fichiers varie d’un système d’exploitation à l’autre.Toutefois, Perl permet d’utiliser systématiquement le séparateur/ dans la fonctionopen, mêmesous Windows où le séparateur est\ .

Page 220: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

228

Page 221: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

CHAPITRE 6

Calculs de fréquences

6.1. Généralités

6.1.1. Les fréquences : de quoi, pourquoi ?

On appelle fréquence d’une unité dans un corpus son nombre d’apparitions (oud’occurrences). Cette unité peut correspondre à tout phénomène repérable automati-quement : un caractère, une séquence de caractères, un mot, un lemme, une catégorie,un patron morphosyntaxique, etc. Le calcul de la fréquence d’une unité donnée est unproblème trivial, dont la seule difficulté réside dans la reconnaissance d’une occur-rence de cette unité.

Le calcul des fréquences d’un ensemble d’unités, par exemple de tous les motscomposant un texte, se ramène par contre à un problème plus complexe, qui est celuide la construction d’une table de fréquence. C’est ce problème, classique en statistiquetextuelle, qui sera développé ici. Les applications de ce genre de calcul sont très nom-breuses, car il constitue la première brique de toute analyse quantitative des donnéestextuelles. Citons quelques scénarios d’utilisation de ces techniques :

– quels sont les mots les plus fréquents dans un texte ? Utilisée en analyse decontenu, cette technique rudimentaire permet de donner un aperçu général de la thé-matique d’un texte ;

– quels sont au contraire les mots qui n’apparaissent qu’uneseule fois dans untexte donné (également appeléshapax) ? Cette méthode permet de repérer des créa-tions lexicales, ou des spécificités du vocabulaire ;

– quels sont les mots les plus fréquents dans le voisinage d’un mot pivot (cooccur-rences) ? Cette information permet par exemple d’étudier l’homogénéité des emploisdu mot visé, en synthétisant ses contextes. Le calcul des cooccurrences est en fait un

229

Page 222: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

230 Perl pour les linguistes

cas particulier d’un calcul de fréquence, pour lequel on se limite à certains segmentsdu corpus d’étude.

Le point commun de ces applications est de produire des résultats permettant derepérer les unités les plus (ou les moins) fréquentes. Ainsi, on cherchera à connaîtreles mots qui se répètent le plus dans un texte, les caractèresou séquences de caractèresles plus utilisés, et les mots apparaissant le plus fréquemment dans le voisinage d’unmot pivot. A l’inverse, certaines études se concentrent essentiellement sur les unitésqui ne se répètent pas. Le calcul de l’ensemble des fréquences pour un type d’unitédonné n’est donc qu’une partie du travail à accomplir. La seconde partie consiste en untri de ces résultats, permettant d’obtenir une liste des unitésclassées par fréquence dé-croissante (ou croissante dans le cas où l’on s’intéresse aux formes rares). Un exempletypique de résultat pour les mots d’un texte est présenté en figure 6.1.

, 3537. 1825de 1232et 1024" 957la 849le 843il 738vous 656les 613à 607nous 564un 558l’ 525d’ 458

Figure 6.1. Extrait de la table des fréquences des formes fléchies desContesde la Bécasse, classées par fréquence décroissante

6.1.2. Principes généraux du calcul de fréquences : algorithme de base

L’algorithme de base permettant de faire ces calculs est très simple. Il se décom-pose en deux étapes :

1) parcours des données, et calcul progressif des fréquences ;

2) tri des données obtenues et affichage.

Plus précisément, cet algorithme tire parti deshachagesde Perl, qui permettentjustement de stocker des couples de données du type (clé, valeur). Dans notre cas, les

Page 223: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Calculs de fréquences 231

clés seront les différents mots ou unités dont on cherche à calculer la fréquence, et lesvaleurs correspondantes seront les fréquences de ces unités.

6.2. Calcul de fréquences simples

Les variantes proposées dans cette section concernent le type d’unité dont on cal-cule la fréquence. Les programmes présentés seront donc destinés à être utilisés surdifférents types de textes, en fonction des annotations et des prétraitements réalisés.

6.2.1. Fréquences des formes fléchies d’un texte segmenté

On cherchera ici à calculer la table de fréquence d’un texte segmenté, dans lequelles mots ont déjà été isolés à raison de un par ligne.

Le programmefrequences-formes.plprend en entrée standard un texte segmentéet produit en sortie la table de fréquence des formes de ce texte, par fréquence décrois-sante. Pour des formes de même fréquence, le tri se fait par ordre lexicographique.

Listing 6.1 – frequences-formes.plTable de fréquence des formes triées par ordre de fréquence décroissante, puis parordre lexicographique

1 use strict;2 use locale;3

4 my %freq;5

6 while ( my $forme = <STDIN> ) 7 chomp $forme;8 $freq lc($forme) ++;9

10

11 my @formes = keys %freq;12 foreach my $forme13 ( sort ($freq$b <=> $freq$a) or ($a cmp $b) @formes ) 14 print $forme, "\t", $freq$forme, "\n";15

Ligne de commande :perl frequences-formes.pl < fichier_segmenté

Exemple :perl frequences-formes.pl < becass2.seg

Résultat :Les premières lignes de résultat sont présentées en figure 6.1.

Page 224: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

232 Perl pour les linguistes

Détails du programme :

Les données d’entrée sont lues ligne par ligne, soit forme par forme. Afin de réunirdes occurrences du même lexème apparaissant avec des différences de casse (majus-cule/minuscule), on utilisera systématiquement la version en lettres minuscules desformes rencontrées en appliquant la fonctionlc. Le calcul de fréquence se fait par laseule instruction de la ligne 8, en augmentant de 1 la valeur associée à la forme dansle hachage%freq . Plus précisément, cette unique instruction regroupe deuxcas defigure distincts :

1) la forme n’a pas encore été rencontrée : elle ne fait pas partie des clés du ha-chage%freq . Dans ce cas, la clé est ajoutée dans le hachage, et sa valeur par défautde zéro est augmentée de 1 (via la notation++) et devient1 ;

2) la forme a déjà été rencontrée, elle fait déjà partie des clés du hachage, sa valeurassociée augmente de 1. Il n’y a pas d’insertion de nouvelle clé dans le hachage,puisque celle-ci y existait déjà.

A la fin du parcours du fichier, le hachage%freq contient donc tous les couples(forme, fréquence) correspondant à l’ensemble des formes distinctes du corpus. Laphase suivante concerne l’affichage en sortie standard de latable de fréquence. L’affi-chage se fait de la façon suivante :

1) toutes les formes seront affichées, une par ligne, suivieschacune d’une tabula-tion et de sa fréquence ;

2) l’ordre de l’affichage est le suivant : les formes de plus haute fréquence d’abord,et en cas de fréquence identique, par ordre lexicographiquecroissant.

L’affichage se fait par parcours exhaustif de la liste des clés du hachage%freq .Cette liste est obtenue grâce à la fonctionkeys, qui renvoie un tableau, stocké icidans la variable@formes . Le tableau ainsi obtenu contient donc la liste de toutesles formes distinctes rencontrées dans les données traitées. Toutefois, l’ordre danslequel les formes apparaissent dans le tableau est totalement arbitraire : il ne s’agit nide l’ordre d’apparition dans le texte, ni de l’ordre lexicographique, et encore moins del’ordre des fréquences correspondantes. Cette situation est systématique avec l’emploid’un hachage : ce type de structure de données a comme rôle de permettre un accèsrapide aux clés et aux valeurs qui y sont stockées. Pour ce faire, Perl organise selondes principes spécifiques les données stockées dans un hachage, et il est nécessaire detrier celles-ci avant de les afficher.

Le tri du tableau@formes se fait à l’aide de la fonctionsort, mais contrairementau comportement par défaut de cette fonction, ce n’est pas untri lexicographique desformes qui est obtenu ici. Il est nécessaire de préciser quelcritère de tri sort doitemployer : ce critère de tri prend la forme d’un bloc (entre accolades) situé entresortet le tableau à trier :($freq$b <=> $freq$a) or ($a cmp $b)

Page 225: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Calculs de fréquences 233

Cette expression indique à la fonction de tri comment elle doit comparer les clésdu hachage. Il est possible de la gloser ainsi : Pour chaque paire de formes$a et $b ,on doit placer$a devant$b si la fréquence de$b ($freq$b ) est inférieure à cellede$a ($freq$a ) ou, si les fréquences sont égales, si$a est placé lexicographi-quement avant$b .

La première partie de cette disjonction (à gauche duor ) indique le critère principaldu tri. Soient deux éléments$a et $b de la liste à trier, ils seront rangés en fonctionde leur valeur associée dans le hachage%freq . La comparaison entre ces valeurs estune comparaison numérique (<=>). Le fait de placer la valeur associée à$b avantcelle associée à$a indique que l’on souhaite un tri décroissant. La seconde partie del’expression de tri indique le critère à utiliser si la première comparaison ne permetpas de différencier les deux éléments (c’est-à-dire si leurs fréquences associées sontidentiques). On effectue alors une comparaison des deux clés suivant l’ordre lexico-graphique (cmp). Le fait de placer$a avant$b indique que l’on souhaite un tri parordre croissant (dea à z). Les deux variables$a et $b , systématiquement employéesdans la définition d’un critère de tri ont un statut spécial etune portée strictementlimitée : elles n’ont pas besoin d’être déclarées dans le programme.

REMARQUE 1.– L’utilisation de l’instructionuse localeau début du code permet d’ef-fectuer le tri lexicographique en respectant l’ordre des caractères accentués du fran-çais. Si l’on omet ces instructions, le résultat du tri est différent : les lettres majusculesseront classées avant les minuscules et les lettres accentuées sont classées après lez.Pour plus de détails voir l’annexe A3.

REMARQUE 2.– Pour certaines analyses, il est préférable de trier les formes par ordrelexicographique et non pas par fréquence, notamment lorsque l’on cherche manuelle-ment dans la table la fréquence de certaines unités. Pour obtenir un tel résultat, il suffitde ne donner aucun paramètre à la fonctionsort dont le comportement par défaut estjustement l’ordre lexicographique croissant. La ligne 13 devient alors :

(sort @formes)

6.2.2. Fréquences des couples (forme/catégorie) d’un texte étiqueté

Le principe de base vu dansfrequences-formes.plpeut être appliqué à des unitésplus complexes qu’une simple forme. L’exemple traité ici correspond au cas où l’onsouhaite calculer la fréquence de couples (forme/catégorie), par exemple pour compa-rer les fréquences relatives deamoureuxen tant que nom et en tant qu’adjectif.

Il est donc nécessaire d’utiliser des données annotées, et plus précisément dansce cas le résultat de l’analyse morphosyntaxique d’un textebrut, réalisée par un outilcomme TreeTagger (voir paragraphe 1.7.3 page 78).

Page 226: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

234 Perl pour les linguistes

Rappelons que les fichiers de ce type contiennent, pour chaque mot du texte uneligne constituée de sa forme, de sa catégorie et de son lemme,séparés par des tabula-tions.

Le programmefrequences-formes-categories.plcalcule ainsi à partir d’un texteétiqueté la table de fréquences de tous les couples (forme/catégorie) et les présente ensortie standard triés par fréquence décroissante. A fréquence équivalente, c’est l’ordrelexicographique de la forme qui est utilisé, et enfin l’ordrelexicographique des caté-gories.

Listing 6.2 – frequences-formes-categories.plTable de fréquences des couples forme/catégorie triée par ordre de fréquence décrois-sante, puis par ordre lexicographique de la forme, puis par ordre lexicographique del’étiquette

1 use strict;2 use locale;3

4 my %freq;5

6 while ( my $ligne = <STDIN> ) 7 chomp $ligne;8 my ( $forme, $categorie, $lemme ) = split( /\t/, $ligne );9 my $couple = lc($forme) . "\t" . $categorie;

10 $freq$couple++;11 12

13 foreach my $couple14 ( sort ( $freq$b <=> $freq$a ) or ( comparer($a, $b) ) 15 keys %freq) 16 print $couple, "\t", $freq$couple, "\n";17 18

19 sub comparer 20 my $couple_a = shift @_;21 my $couple_b = shift @_;22 my ( $forme_a, $categorie_a ) = split( /\t/, $couple_a );23 my ( $forme_b, $categorie_b ) = split( /\t/, $couple_b );24 return(25 ($forme_a cmp $forme_b) or ($categorie_a cmp $categorie_b ) );26

Ligne de commande :perl frequences-formes-categories.pl < texte_étiqueté

Exemple :perl frequences-formes-categories.pl < becass2.tag

Résultat (extrait) :, PUN 3537

Page 227: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Calculs de fréquences 235

. SENT 1825

de PRP 1232

et KON 1024

...

arrêtèrent VER:simp 2

arrivions VER:impf 2

asseoir VER:infi 2

assurément ADV 2

...

amoureux ADJ 1

amoureux NOM 1

...

Détails du programme :

Commefrequences-formes.pl, ce programme utilise aussi un hachage dont les clésseront des chaînes de caractères constituées d’une forme (mise en minuscules) et d’unecatégorie séparées par une tabulation. La forme et la catégorie sont obtenues en seg-mentant la ligne en se basant sur la tabulation (ligne 8) selon la méthode expliquéepour le listing 5.13 (page 219). Le lemme, qui ne sera pas utilisé ici, est toutefoisfourni par le découpage en troisième position, et est stockédans la variable$lemme.

Une fois les deux éléments (forme et catégorie) repérés, il suffit de mettre la formefléchie en minuscules, puis de reconstruire le couple par concaténation en réinsérantune tabulation comme séparateur. C’est ce nouveau couple (variable$couple ) quisert alors de clé pour le hachage%freq , dont le remplissage se fait de la même façonque dansfrequences-formes.pl.

Une fois le hachage rempli, il faut comme précédemment le trier et l’afficher. Letri lexicographique de clés qui comportent des séparateurs(espace, tabulation, barreoblique, etc.) comporte une difficulté car ces caractères sont ignorés lors de la compa-raison. Ainsi, si l’on effectuait la même opération de tri que dans le cas précédent, descouples comme :marche VER

marcher VER

seraient triés dans l’ordre inverse de celui présenté ci-dessus, puisque la tabulationn’est pas prise en compte. Plus précisément, cela revient, pour le programme, à trierles deux chaînes suivantes :marcheVER

marcherVER

Ce qui donne donc un résultat inverse à l’attendu (marcher sera placé avantmarche). Pour éviter ce problème, il faut donc faire appel à une fonction de comparai-son (comparer ). Cette fonction reçoit comme paramètre deux couples à comparer

Page 228: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

236 Perl pour les linguistes

(stockés dans les variables locales$couple_a et$couple_b ), et les décomposentchacun en formes et catégories. La valeur de retour de la fonction est le résultat de lacomparaison des deux couples, basée d’abord sur l’ordre lexicographique des formes(via l’expression$forme_a cmp $forme_b ), en utilisant l’opérateur de compa-raison lexicographiquecmp. Si les formes sont identiques, les catégories sont alorsutilisées avec le même opérateur ($categorie_a cmp $categorie_b ).

Toutefois, lors de la définition du critère de tri communiquéàsort (ligne 14), c’estla fréquence qui est le critère principal.

REMARQUE.– Pour simplifier le code, la liste des clés du hachage%freq n’est pasexplicitement stockée dans une variable de type tableau comme c’était le cas dans leprogrammefrequences-formes.pl. C’est donc directement sur la liste des clés obtenuesparkeys %freq que s’applique le tri.

6.2.3. Rang des lemmes

Le calcul de fréquence peut aussi être utilisé pour déterminer lerang des lemmesou des formes d’un texte (c’est-à-dire en attribuant le rang1 au plus fréquent, puisle rang 2 au second plus fréquent, etc.). Ces informations peuvent par exemple ser-vir à comparer l’utilisation d’une unité entre plusieurs textes en faisant abstractiondu nombre total de mots de ceux-ci. Le calcul de rang est identique au calcul desfréquences excepté que l’on affiche pour chaque entrée son ordre dans la liste desfréquences triées.

Le tableau ci-dessous présente les rangs de quelques lemmesdesContes de laBécasse:, 1

le 2

. 3

de 4

et 5

...

bras 71

monsieur 71

quelque 71

passer 72

Le programmerang-lemme.plpermet de calculer le rang des lemmes à partir d’untexte étiqueté et lemmatisé par TreeTagger fourni en entréestandard.

Page 229: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Calculs de fréquences 237

Listing 6.3 – rang-lemme.plRang des lemmes triés par fréquence décroissante

1 use strict;2 use locale;3

4 my %freq;5

6 while ( my $ligne = <STDIN> ) 7 chomp $ligne;8 my ( $forme, $categorie, $lemme ) = split( /\t/, $ligne );9 $freq$lemme++;

10 11

12 my @liste = sort13 $freq$b <=> $freq$a or ($a cmp $b) keys %freq;14

15 my $rang = 1;16 print $liste[0], "\t", $rang, "\n";17

18 for ( my $i = 1; $i <= $#liste; $i++ ) 19 if( $freq$liste[$i] < $freq$liste[$i-1] ) 20 $rang++;21 22 print $liste[$i], "\t", $rang, "\t", $freq$liste[$i], " \n";23

Ligne de commande :perl rang-lemme.pl < texte_étiqueté

Exemple :perl rang-lemme.pl < becass2.tag

Résultat : voir tableau précédent.

Détails du programme :

Ce programme reprend les mêmes principes quefrequence-forme-categorie.plpour le calcul des fréquences des lemmes dans le hachage%freq .

Les clés de%freq sont ensuite triées suivant les mêmes principes (fréquencedécroissante, puis à fréquence égale ordre lexicographique). Toutefois, le résultat n’estpas immédiatement affiché mais stocké dans le tableau@liste , puisque le rang dechaque élément de@liste doit d’abord être calculé.

Cette opération pose une petite difficulté liée aux lemmes ayant la même fré-quence : dans ce cas, leur rang est identique, il y a donc une différence entre le ranget la position du lemme dans la liste triée. Pour calculer le rang de chaque lemme,l’algorithme suivant est employé :

– le rang du premier lemme de la liste est 1 ;

Page 230: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

238 Perl pour les linguistes

– pour les autres lemmes :- si leur fréquence est strictement inférieure à celle du lemme précédent on

augmente le rang de 1 ;- sinon, la fréquence est identique et le rang n’est pas modifié.

Le tableau ci-dessous détaille les fréquences et rangs calculés pour une série delemmes. Le calcul du rang se fait des fréquences les plus élevées vers les fréquencesles plus basses. Si le rang debrasest 70, alorsmonsieurqui est immédiatement aprèslui a un rang de 71 puisque sa fréquence est inférieure (54 contre 55). Par contre,quelqueayant la même fréquence que son prédécesseur, a la même valeur de rang(71).

Couple FréquenceRang calculébras 55 70monsieur 54 71quelque 54 71passer 52 72

Dans le programme, la boucle parcourant la liste (basée sur l’index $i ) doit doncdémarrer au second élément de la liste ($i est initialisé à 1). L’élément numéro$ide@liste (noté$liste[$i] ) voit donc son rang ($rang ) calculé en comparantsa fréquence ($freq$liste[$i] ) à celle de son prédécesseur dans le tableau($freq$liste[$i-1] ).

Les méthodes présentées dans cette section sont bien entendu adaptables à toutesorte d’unités. Les seules variations sont généralement les méthodes permettant derepérer les unités en question. Ces méthodes sont explicitées au chapitre 5. Il est ainsitout à fait envisageable de calculer la fréquence de séquences de plusieurs mots, ou aucontraire les fréquences de terminaisons de mots.

6.3. Cooccurrences

On appellecooccurrentsd’une unité linguistique particulière (appeléepivot) lesunités qui apparaissent dans le voisinage de celle-ci. Cette notion sert généralement àobserver les mots qui apparaissent le plus fréquemment à proximité les uns des autres.

La notion de voisinage est généralement définie en termes de fenêtre autour dupivot, la taille de la fenêtre étant généralement calculée en nombre de mots. Ainsi,avec une fenêtre de taille 3, les 6 cooccurrents d’un mot du texte sont les mots situés àune distance d’au plus 3 mots du pivot (à droite et à gauche). Toutefois, on ne considèrepas comme cooccurrents des mots situés dans des phrases différentes.

Page 231: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Calculs de fréquences 239

EXEMPLE.– Dans la phraseLes voix descoqsentraient par la porte grande ouverteles cooccurrents decoqssont, pour une fenêtre de 3 mots :les, voix, des, entraient,par et la.

Au final, on considérera bien sûr les fréquences cumulées descooccurrents detoutes les occurrences du pivot.

L’intérêt de l’étude des cooccurrences est qu’elles permettent de caractériser demanière synthétique les contextes d’utilisation du pivot.On peut ainsi repérer simple-ment les mots ayant une relation syntaxique (c’est-à-dire les verbes dont le pivot estl’objet ou le sujet) ou sémantique (les mots en coordination), etc.

De façon plus précise, on cherche à calculer la fréquence descooccurrents d’unpivot, c’est-à-dire que l’on s’intéressera préférentiellement aux mots qui apparaissentfréquemment dans son voisinage. La fréquence de cooccurrence, par opposition à lafréquence absolue, n’est donc plus liée uniquement au mot considéré, mais au pivotet au mot. La figure 6.2 contient la table de fréquence des cooccurrents du motneigedans lesContes de la Bécasseavec une fenêtre de taille 3.

coqs les 3coqs , 1coqs chantaient 1coqs comme 1coqs dans 1coqs des 1coqs entraient 1coqs la 1coqs par 1coqs voix 1----------neige la 6neige qui 2neige tombait 2neige , 1neige à 1neige commençait 1neige complétait 1neige en 1neige épaisse 1neige jour 1neige le 1neige maintenant 1neige poudrait 1neige sang 1neige sous 1neige sur 1neige tomber 1neige toujours 1neige voyant 1

Figure 6.2. Cooccurrents (formes de surface) decoqset deneigedans lesContes de la Bécassepour une fenêtre de taille 3, par fréquence décroissante

Page 232: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

240 Perl pour les linguistes

Cette présentation est celle d’une table de fréquence classique, dont les fréquencesne sont plus absolues mais relatives au pivot. On peut y noterla présence de l’articlela, mais aussi du verbetombait, traduisant bien l’emploi classique de ce nom dans desphrases du typela neige tombait.

S’il est assez simple d’obtenir une telle information pour un mot donné, le géné-raliser à l’ensemble des mots d’un texte (en les considérantchacun tour à tour commepivot) nécessite une approche plus complexe, basée sur une structure de données par-ticulière.

La structure de données utilisée pour ce calcul est unhachage de hachages, c’est-à-dire une structure de données complexe dans laquelle, à chaque mot du corpus, estassocié un hachage simple, qui à son tour associe une fréquence à chacun des cooc-currents de ce mot. On peut également considérer les hachages de hachages commedes hachages à double clé : dans ce cas la clé principale est lepivot, la clé secondaireun cooccurrent du pivot, et la valeur la fréquence associée.

La figure 6.3 présente un extrait de la structure obtenue. Lespivotscoqset neigesont les clés principales, et leur valeur associée est elle-même un hachage dont les cléssont les cooccurrents et les valeurs les fréquences.

8

>

>

>

>

>

>

>

>

>

>

>

>

>

>

<

>

>

>

>

>

>

>

>

>

>

>

>

>

>

:

coqs ⇒

8

>

>

<

>

>

:

les ⇒ 3

, ⇒ 1

chantaient ⇒ 1

...

neige ⇒

8

>

>

<

>

>

:

la ⇒ 6

qui ⇒ 2

tombait ⇒ 2

...

...

Figure 6.3. Schéma du hachage de hachages utilisé pour stocker lescooccurrents

Le principe de ce type de structures complexes est détaillé en annexe A4, maisnous expliciterons leur manipulation dans les exemples traités ici.

La première étape du programme consiste simplement à parcourir l’ensemble dutexte, et à repérer les couples de mots entrant dans une relation de cooccurrence. L’en-semble de ces couples, ainsi que la fréquence de cooccurrence, seront intégralementstockés dans le hachage de hachages. Cette étape sera toutefois un peu plus complexe,car on devra se limiter aux relations au sein des phrases.

Page 233: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Calculs de fréquences 241

La seconde étape consiste en l’affichage des résultats. Pourchaque mot du corpus,considéré à son tour comme pivot, il s’agit d’afficher la table de fréquence de sescooccurrents, suivant les modalités vues dans les programmes précédents.

Nous présentons ci-dessous le code de ces programmes, en distinguant différentesversions en fonction des types de données analysées.

6.3.1. Cooccurrences des formes d’un texte étiqueté

Le premier programme se base sur un texte étiqueté et lemmatisé, mais calculeles cooccurrents des formes de surface. L’intérêt d’utiliser un texte étiqueté est qu’ilest possible d’y repérer les frontières de phrase. La logique de la cooccurrence étantd’identifier les mots entretenant des relations syntaxiques ou sémantiques avec le pi-vot, il n’est pas judicieux de considérer des couples de motssitués dans des phrasesdistinctes.

Le programmecooccurrences-formes.plcalcule donc l’ensemble des cooccurrentsde chaque mot d’un texte étiqueté fourni en entrée standard.Les résultats affichéssont, pour chaque forme (considérée comme pivot), la table de fréquence de ses cooc-currents. Ces cooccurrents sont affichés par fréquence décroissante, puis à fréquenceégale par ordre lexicographique.

Listing 6.4 – cooccurrences-formes.plCooccurrents des formes simples d’un texte étiqueté

1 use strict;2 use locale;3

4 my $fenetre = 3;5 my( @phrase, %cooc );6

7 while (my $ligne = <STDIN>) 8 chomp $ligne;9 my ( $forme, $etiquette, $lemme ) = split( /\t/, $ligne );

10 if ( $etiquette ne "SENT" ) 11 push ( @phrase, $forme );12 13 else 14 for ( my $i = 0; $i <= $#phrase; $i++ ) 15 my $pivot = lc( $phrase[$i] );16 for ( my $j = $i-$fenetre; $j <= $i+$fenetre; $j++ ) 17 if ( ( $j >= 0 ) and18 ( $j <= $#phrase ) and19 ( $j != $i ) ) 20 my $cooccurrent = lc ($phrase[$j]);21 $cooc$pivot$cooccurrent++;22 23 24

Page 234: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

242 Perl pour les linguistes

25 @phrase = ();26 27 28

29 foreach my $pivot ( sort keys %cooc ) 30 my %cooc_pivot = % $cooc$pivot ;31 foreach my $cooccurrent32 ( sort $cooc_pivot$b <=> $cooc_pivot$a or $a cmp $b33 keys %cooc_pivot ) 34 print $pivot, "\t", $cooccurrent, "\t",35 $cooc_pivot$cooccurrent, "\n";36 37 print "----------\n";38

Ligne de commande :perl cooccurrences-formes.pl < texte_étiqueté

Exemple :perl cooccurrences-formes.pl < becass2.tag

Résultat (extrait) :- , 17

- c’ 5

- nous 5

- vous 5

...

----------

coqs les 3

coqs , 1

coqs chantaient 1

...

----------

neige la 6

neige qui 2

neige tombait 2

neige , 1

neige à 1

...

REMARQUE.– Les cooccurrents sont regroupés par pivot, et sont séparés par une lignede tirets de ceux des autres pivots. L’ordre lexicographique appliqué place en tête desrésultats les signes de ponctuation (considérés comme des mots), ce qui explique quele tiret est le premier pivot présenté.

Ce programme produit un résultat assez volumineux, même pour un texte relative-ment court (plus de 120 000 lignes de résultat pourbecass2.tag) : il est très fortement

Page 235: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Calculs de fréquences 243

conseillé d’en rediriger la sortie dans un fichier texte plutôt que de la visualiser dansun terminal. Le programme de la section suivante propose un mode d’interrogationdes résultats plus adapté à un usage dans un terminal.

Détails du programme :

Au cours de la lecture de ce fichier, on procède à un découpage des lignes pour enextraire la forme, le lemme et l’étiquette. Puisque les cooccurrences ne sont considé-rées qu’au sein d’une phrase, il convient de traiter ces données phrase par phrase. Laboucle principale (lignes 7 à 27) est donc découpée comme suit : si le mot n’est pasun délimiteur de phrase (étiquetéSENTpar TreeTagger), on se contente de stocker saforme dans le tableau@phrase (ligne 11). Par contre, si le mot est un délimiteur dephrase, alors il est nécessaire d’effectuer le calcul des cooccurrences en parcourant letableau@phrase .

Pour cette étape (lignes 14 à 25), une première bouclefor sur l’index$i concernechaque mot de la phrase tout à tour considéré comme pivot (variable$pivot ). Unefois le pivot sélectionné, une seconde boucle (lignes 16 à 23) va parcourir la fenêtrequi l’entoure, et dont la taille est ici fixée par la variable$fenetre en début deprogramme (ici3). La variable$j parcourt donc une plage de valeurs autour de laposition du pivot (soit de($i - $fenetre) à ($i + $fenetre) ). Chaquemot de cette plage est un cooccurrent du pivot à l’exception :

– des cas où il se situe en-dehors des limites de la phrase où setrouve le pivot (àgauche ou à droite), ce qui se traduit par des valeurs seuil pour $j : il doit être positifet ne pas dépasser la position du dernier mot de la phrase ;

– du pivot lui-même ($j coïncide avec$i ).

Un cooccurrent retenu est ensuite mis en minuscules puis stocké dans la variable$cooccurrent . Pour chaque couple (pivot/cooccurrent), l’information doit ensuiteêtre stockée dans le hachage de hachages.

Cette structure est manipulée en Perl de la façon suivante :

– il s’agit avant tout d’un hachage, et la variable est repérée par%cooc ;

– les clés de ce hachage sont les pivots ($pivot ), on utilise donc la nota-tion habituelle des hachages pour identifier les valeurs associées aux clés, soit :$cooc$pivot ;

– par contre, la valeur associée à un pivot est elle-même un hachage : il est doncnécessaire de préciser quelle est la clé de ce second hachageimbriqué. La notation laplus adaptée consiste à placer à la suite de la clé principale($pivot ) la seconde clé($cooccurrent ) dans une seconde paire d’accolades ;

– l’expression complète$cooc$pivot$cooccurrent identifie doncune valeur scalaire : la fréquence de$cooccurrent autour de$pivot . C’est cettefréquence qui augmente de 1 comme il est habituel pour les calculs de fréquence.

Page 236: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

244 Perl pour les linguistes

Une fois tous les mots de la phrase ainsi traités, le tableau@phrase est réinitialisé(c’est-à-dire vidé), et la phrase suivante peut alors y êtrestockée lors du prochainpassage dans la boucle.

La fin de ce programme concerne l’affichage de la table de fréquence des cooccur-rents. L’ordre d’affichage est le suivant : pour chaque pivot(dans l’ordre lexicogra-phique croissant), ses cooccurrents sont affichés par ordrede fréquence décroissante(puis par ordre lexicographique croissant en cas de fréquences égales).

L’affichage nécessite donc de parcourir le hachage de hachages par une doubleboucle : la première sur les clés principales (pour fixer le pivot), et la seconde sur lesclés secondaires (cooccurrents), une fois le pivot fixé.

La première boucleforeach parcourt donc la liste des pivots triés par ordre lexi-cographique. Ces pivots sont les clés principales du hachage de hachages, et doncaccessiblesvia la fonctionkeyscomme pour les hachages simples.

Une fois le pivot fixé (variable$pivot ), il est possible d’accéder au hachagesimple qui lui est associé au moyen de l’instruction suivante :

my %cooc_pivot = % $cooc$pivot ;

Cette instruction recopie dans un hachage simple (%cooc_pivot ) les informa-tions associées à$pivot dans%cooc. La notation spécifique à droite de l’affectationindique que la valeur associée n’est pas un simple scalaire,mais bien une structure dedonnées, ce qui est précisé par la notation%... . Une fois cette copie obtenue, lecontenu de%cooc_pivot est parcouru et affiché comme on l’a vu pour les tablesde fréquences classiques. Plus de détails sur l’utilisation des structures de donnéescomplexe sont disponibles en annexe A4.

Pour des questions de lisibilité, une ligne de tirets est affichée lors du changementde pivot, à la fin du corps de la boucle principale.

6.3.2. Cooccurrences des lemmes d’un texte étiqueté après sélection de la catégorieet filtrage

La version minimale présentée ci-dessus donne des résultats généralement assezdécevants, puisque la cooccurrence se fait sur l’ensemble des mots et signes de ponc-tuation. Il n’est donc pas rare de trouver la virgule ou la prépositiondecomme cooc-currence la plus fréquente d’un mot. Pour pallier ce problème, il est tout à fait possibled’imposer des contraintes sur les cooccurrents potentielsainsi que sur leur position.La version présentée ici propose de telles restrictions :

Page 237: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Calculs de fréquences 245

– la restriction de la catégorie morphosyntaxique du cooccurrent. En se concen-trant sur des catégories ouvertes (noms, adjectifs, verbesou adverbes), on évite ainside voir apparaître ce que certaines applications appellentdesmots vides, ou gramma-ticaux, tels que les pronoms, prépositions, conjonctions,etc. ;

– l’utilisation d’un antidictionnaire, c’est-à-dire d’une liste prédéfinie de mots quiseront ignorés dans la prise en compte des cooccurrents. Cette technique permet de nepas tenir compte de certains mots trop fréquents ou que l’on ne souhaite pas prendreen compte, même si leur catégorie est une de celles retenues lors de la restrictionprécédente ;

– le paramétrage du sens de la relation de cooccurrence. Pourcertaines études,il n’est pas nécessaire de prendre en compte les cooccurrents à gauche du pivot (ouà droite). Dans d’autres cas, la distance considérée entre le pivot et son cooccurrentpeut varier suivant le sens. Afin de paramétrer ceci, nous proposons de définir pourles contextes gauche et droit du pivot deux fenêtres indépendantes. Une fenêtre detaille nulle pour l’un des deux contextes indiquera que l’onne souhaite pas prendre encompte les cooccurrents dans cette direction ;

– l’utilisation des lemmes et non des formes de surface afin deregrouper les unitéslexicales apparaissant sous différentes formes fléchies.

L’antidictionnaire requiert la gestion suivante : on suppose tout d’abord que cetteressource est disponible dans un fichier nomméantidictionnaire.txt et placédans le répertoire où se trouve le programme. Ce fichier contient simplement un motpar ligne, tout mot présent dans ce fichier sera exclu du calcul des cooccurrents. Onsuppose également que les mots de l’antidictionnaire y sontprésents sous leur formede citation (lemme). Pour les exemples traités ici, nous utilisons le fichier suivant quiliste les auxiliaires et les principaux verbes modaux :

aller

avoir

devoir

être

falloir

pouvoir

Enfin, il est possible, au lieu d’afficher comme résultat l’ensemble des couples encooccurrence (ce qui donne lieu à des données très volumineuses), de procéder à unaffichage interactif, en laissant l’utilisateur choisir lepivot dont il souhaite voir lescooccurrents.

Le programmecooccurrences-lemmes-filtre.plmet en place l’ensemble de ces mo-difications.

Page 238: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

246 Perl pour les linguistes

Listing 6.5 – cooccurrences-lemmes-filtre.plCooccurrents filtrés des lemmes d’un texte étiqueté

1 use strict;2 use locale;3

4 my $fen_gauche=0;5 my $fen_droite=3;6 my $cat_cooc="(VER|NOM|ADV|ADJ)";7

8 my (%antidico, %cooc, @cat_phrase, @lemme_phrase);9

10 if ( $#ARGV !=0 ) 11 die "Usage : ", $0, " texte_étiqueté\n";12 13

14 open( ANTIDICO,"<", "antidictionnaire.txt" ) or15 die "Impossible d’ouvrir antidictionnaire.txt : ", $!, "\n ";16

17 while ( my $ligne = <ANTIDICO> )18 chomp $ligne;19 $antidico$ligne = 1;20 21 close ANTIDICO;22

23 open ( TEXTE, "<", $ARGV[0] ) or24 die "Impossible d’ouvrir ",$ARGV[0], " : ", $!, "\n";25

26 while ( my $ligne = <TEXTE> )27 chomp $ligne;28 my ( $forme, $categorie, $lemme ) = split( /\t/, $ligne );29 if ( $categorie ne "SENT" ) 30 push ( @lemme_phrase, $lemme );31 push ( @cat_phrase, $categorie );32 33 else 34 for ( my $i=0; $i<=$#lemme_phrase; $i++ ) 35 my $pivot = $lemme_phrase[$i];36 for (my $j=($i-$fen_gauche); $j<=($i+$fen_droite); $j++ )37 if ( ($j >= 0) and38 ($j <= $#lemme_phrase) and39 ($j != $i) and40 (not defined($antidico$lemme_phrase[$j])) and41 ($cat_phrase[$j] =~ /$cat_cooc/)42 ) 43 $cooc$pivot$lemme_phrase[$j]++;44 45 46 47 @lemme_phrase=();48 @cat_phrase=();49 50 51

52 close TEXTE;53

54 print "Quel pivot ? (X pour finir) : ";55 my $pivot = <STDIN>;56 chomp $pivot;57 while ( $pivot ne "X" )58 if ( defined ( $cooc$pivot ) )

Page 239: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Calculs de fréquences 247

59 my %cooc_pivot = %$cooc$pivot;60 foreach my $cooccurrent (61 sort 62 ($cooc_pivot$b <=> $cooc_pivot$a) or63 ($a cmp $b) 64 keys %cooc_pivot) 65 print $cooccurrent, "\t",66 $cooc_pivot$cooccurrent,"\n";67 68 69 else 70 print "\"",$pivot, "\" n’a pas de cooccurrents !\n";71 72 print "Quel pivot ? (X pour finir) : ";73 $pivot = <STDIN>;74 chomp $pivot;75

Ligne de commande :perl cooccurrences-lemmes-filtre.pl texte_étiqueté

Exemple :perl cooccurrences-lemmes-filtre.pl becass2.tag

Exemple d’interaction : (les chaînes saisies par l’utilisateur sont en gras)Quel pivot ? (X pour finir) : coq

chanter 2

entrer 1

percher 1

Quel pivot ? (X pour finir) : neige

tomber 3

commencer 1

compléter 1

épais 1

jour 1

maintenant 1

poudrer 1

remuer 1

toujours 1

Quel pivot ? (X pour finir) : mouton

"mouton" n’a pas de cooccurrents !

Quel pivot ? (X pour finir) : X

A la différence des programmes précédents, le fichier contenant le texte est icicommuniqué au programme en tant que paramètre. Ceci est dû aufait que l’entréestandard est dédiée à la lecture des pivots indiqués par l’utilisateur.

Page 240: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

248 Perl pour les linguistes

Comme on peut le voir dans les exemples ci-dessus, les résultats sont largementplus restreints que ceux fournis parcooccurrences-formes.pl, mais aussi plus facile-ment interprétables. Les paramètres utilisés pour obtenirle résultat précédent sont :

– la limitation aux seules catégories ouvertes (verbe, nom,adjectif et adverbe) ;

– l’utilisation d’une fenêtre de 3 mots à droite du pivot (et de taille nulle à gauche) ;

– l’élimination des verbes modaux.

Les critères de tri restent les mêmes que ceux du programme précédent (ordrelexicographique du pivot, puis fréquence, et enfin ordre lexicographique des cooccur-rents).

Détails du programme :

Les différentes phases decooccurrences-lemmes-filtre.plsont les suivantes :

– définition des différents paramètres (dimensions de la fenêtre, catégories des co-occurrents) et ouverture du fichier dont le nom est indiqué enparamètre ;

– lecture du fichierantidictionnaire.txt et stockage de son contenu dansle hachage simple%antidico ;

– parcours du texte étiqueté phrase par phrase, avec sélection des pivots et descooccurrents en fonction des contraintes ;

– lecture des pivots indiqués par l’utilisateur, et affichage des cooccurrents cor-respondants triés. Cette dernière phase est répétée autantde fois que l’utilisateur lesouhaite, en indiquant de nouveaux pivots sans répéter pourautant l’ensemble descalculs.

Le nom du fichier étant communiqué au programme sous forme de paramètre, ilest nécessaire de vérifier avant tout que la ligne de commandeest correcte, commecela est présenté en section 3.9 (page 155). Le fichier contenant le texte étiqueté estensuite ouvert en lecture en utilisant le descripteurTEXTE.

L’antidictionnaire est ensuite chargé en mémoire en lisantle fichierantidictionnaire.txt . Les entrées de l’antidictionnaire sont stockées commeclés dans le hachage%antidico , ce qui permet un accès rapide lors de l’applicationde cette contrainte. Il est en effet nécessaire de vérifier pour chaque mot du texte sonéventuelle présence dans la liste. La valeur associée est ici arbitraire (la valeur numé-rique 1) : seule importe au bout du compte la présence du mot dans la liste des clefsdu hachage.

Les restrictions sur les catégories des cooccurrents sont exprimées à l’aide de lavariable$cat_cooc . Cette variable contient une expression régulière qui seramiseen correspondance avec les catégories des mots du texte étiqueté. L’expression utiliséeici indique (par une disjonction) que l’on ne retiendra que les verbes (VER), noms

Page 241: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Calculs de fréquences 249

(NOM), adverbes (ADV) et adjectifs (ADJ), mais peut bien entendu être modifiée sil’on souhaite s’intéresser à d’autres types de catégories.

Les dimensions de la fenêtre autour du pivot sont exprimées par deux variablesscalaires qui peuvent également être modifiées :$fen_gauche et$fen_droite .

Le parcours du fichier se fait de façon très similaire au cas précédent. Les diffé-rences sont les suivantes :

– les restrictions sur les catégories des cooccurrents impliquent que l’on ait accèsaux catégories des mots de la phrase, en plus de leurs lemmes.Ainsi, deux tableauxsont construits pour chaque phrase :@lemme_phrase et@cat_phrase . Ces deuxtableaux sont construits de façon parallèle : les informations concernant un même motse situent à la même position dans les deux tableaux ;

– la boucle autour du pivot prend en compte les deux valeurs différenciées pourles dimensions de la fenêtre ;

– la prise en compte d’un cooccurrent est soumise à deux contraintes supplémen-taires : il doit être absent de l’antidictionnaire et sa catégorie doit correspondre à celledéfinie dans$cat_cooc .

La phase finale d’interrogation se fait en demandant à l’utilisateur d’indiquer lepivot dont il souhaite voir les cooccurrents. Ces pivots sont lus en entrée standard,jusqu’à ce que l’utilisateur indique la fin de son interrogation (et donc du programme)en entrantX. Pour chaque pivot indiqué, la liste des cooccurrents va être calculée, triéeet affichée comme danscooccurrences-formes.pl, mais ici la boucle sur l’ensembledes clés du hachage de hachages n’est bien entendu pas mise enplace, le pivot étantentré par l’utilisateur. Si le mot indiqué n’est pas une clé du hachage de hachages, unmessage est affiché et aucun calcul n’est effectué.

6.3.3. Utilisation de mesures statistiques – L’information mutuelle

La mesure de la force d’une association lexicale est rarement liée à la seule fré-quence de cooccurrence. Cette mesure ne tient notamment pascompte de la fréquencetotale des unités individuelles mises en relation. Ainsi, pour un nom, le cooccurrentle plus fréquent a de grande chance d’être un article (le, la, un, une) puisque ces motsapparaissent avec de très hautes fréquences. Certaines mesures statistiques couram-ment utilisées en linguistique de corpus permettent de faire la part des choses entredes cooccurrents pertinents et ceux qui ne sont liés qu’à deseffets de fréquence. Unedes mesures classiques utilisées est l’information mutuelle (mutual information), dontla formule est la suivante (établie à partir de la définition de [MAN 99, p. 68]) :

I(x, y) = log2

f(x, y)N

f(x)f(y)

Page 242: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

250 Perl pour les linguistes

où x et y sont deux unités dont on cherche à calculer l’information mutuelleI (dansnotre cas deux mots),f(x) est la fréquence absolue de l’unitéx, f(x, y) la fréquenceà laquellex et y apparaissent en cooccurrence, etN la taille du corpus en nombred’occurrences.log2 fait référence au logarithme en base 2.

Cette mesure permet donc de pondérer la fréquence d’un cooccurrent par la fré-quence de chacune des unités mises en jeu. Par exemple, l’information mutuelle entreun nom et un déterminant en cooccurrence fréquente sera trèsfaible par le fait quela fréquence du déterminant sera très importante. L’utilisation d’un logarithme per-met essentiellement de rendre plus facilement comparablesdes nombres très petitsrésultant de la fraction.

Le programmeinfomutuelle.pldécrit dans le listing 6.6 se borne à calculer les co-occurrents des lemmes du texte, sans liste de mots vides ni defiltrage sur les catégoriesmorphosyntaxiques, mais en rangeant les cooccurrents d’unlemme par informationmutuelle décroissante. Son fonctionnement est, du point devue de son utilisation,identique à celui decooccurrences-lemmes-filtre.pl.

Listing 6.6 – infomutuelle.plCooccurrents des lemmes d’un texte étiqueté triés par information mutuelle

1 use strict;2 use locale;3

4 my $fenetre = 3;5 my ($n_forme, %cooc, @phrase, %freq, %infomut );6

7 if ( $#ARGV !=0 ) 8 die "Usage : ", $0, " texte_étiqueté\n";9

10

11 open ( TEXTE, "<", $ARGV[0] ) or12 die "Impossible d’ouvrir ",$ARGV[0], " : ", $!, "\n";13

14 while ( my $ligne = <TEXTE> ) 15 chomp $ligne;16 my ( $forme, $etiquette, $lemme ) = split( /\t/, $ligne );17 if ( $etiquette ne "SENT" ) 18 push ( @phrase, $lemme );19 $freqlc $lemme++;20 $n_forme++;21 22 else 23 for ( my $i = 0; $i <= $#phrase; $i++ ) 24 my $pivot = lc($phrase[$i]) ;25 for ( my $j = $i-$fenetre; $j <= $i+$fenetre; $j++ ) 26 if ( ($j >= 0) and27 ($j <= $#phrase)28 and ($j != $i) ) 29 my $cooccurrent= lc($phrase[$j]);30 $cooc$pivot$cooccurrent++;31

Page 243: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Calculs de fréquences 251

32 33 34 @phrase = ();35 36 37 close TEXTE;38

39 foreach my $pivot ( keys %cooc )40 foreach my $cooccurrent ( keys %$cooc$pivot )41 $infomut$pivot$cooccurrent =42 log( ( $n_forme * $cooc$pivot$cooccurrent ) /43 ( $freq$pivot * $freq$cooccurrent )44 ) / log(2);45 46 47

48 print "Quel pivot ? (X pour finir) : ";49 my $pivot = <STDIN>;50 chomp $pivot;51 while ( $pivot ne "X" )52 if ( defined ( $infomut$pivot ) ) 53 my %infomut_pivot = % $infomut$pivot ;54 foreach my $cooccurrent55 (sort $infomut_pivot$b <=> $infomut_pivot$a56 or $a cmp $b57 keys %infomut_pivot) 58 print $cooccurrent, "\t",59 sprintf("%.2f", $infomut_pivot$cooccurrent), "\n

";60 61 62 else 63 print "\"",$pivot, "\" n’a pas de cooccurrents !\n";64 65 print "Quel pivot ? (X pour finir) : ";66 $pivot = <STDIN>;67 chomp $pivot;68

Ligne de commande :perl infomutuelle.pl texte_étiqueté

Exemple :perl infomutuelle.pl becass2.tag

Exemple d’interaction : (les chaînes saisies par l’utilisateur sont en gras)Quel pivot ? (X pour finir) : neige

duvet 12,35

poudrer 12,35

compléter 11,35

silence 10,35

épais 10,02

léger 9,54

Page 244: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

252 Perl pour les linguistes

tomber 8,93

remuer 8,89

...du 4,12

en 3,65

le 3,45

à 3,16

et 2,40

, 0,61

Comme on peut le voir dans cet extrait montrant les cooccurrents deneige, lesmots dont la fréquence est très élevée (à, et, le, du, etc.) sont relégués en fin de liste :leur cooccurrence avecneigen’est pas spécifique, au contraire deduvetetpoudrerparexemple.

Détails du programme :

Afin de calculer l’information mutuelle pour chaque couple de lemmes entrant encooccurrence, nous avons besoin de la fréquence absolue de chaque lemme, ainsi quedu nombre total de mots du corpus. La fonction logarithme estprédéfinie en Perl :log.

Ainsi, en plus du hachage de hachages%cooc, dont le fonctionnement sera lemême que précédemment et compte la fréquence des cooccurrents, nous avons besoind’un hachage simple (%freq ) pour calculer les fréquences individuelles, d’un scalaire$n_forme pour compter les mots, et d’un second hachage de hachages,%infomutqui contiendra la mesure de l’information mutuelle calculée.

Les correspondances entre les éléments de la formule et les expressions en codePerl sont donc les suivantes, pour deux lemmesx ety stockés dans les variables$x et$y :

– I(x, y)⇔ $infomut$x$y

– N ⇔ $n_forme

– f(x, y)⇔ $cooc$x$y

– f(x)⇔ $freq$x

Les variables%cooc, %freq et $n_forme doivent être remplies lors du par-cours du fichier. Par contre, l’information mutuelle ne peutêtre calculée qu’unefois que toutes ces données sont disponibles, en parcourantl’ensemble des couplesde lemmes en cooccurrence (lignes 39 à 46). Une fois le hachage de hachages%infomut disponible, le tri et l’affichage se font de la même manière que précé-demment.

Toutefois, en ce qui concerne l’affichage, l’information mutuelle est une valeurobtenue par la fonction logarithme et s’exprime par un nombre réel. L’affichage de

Page 245: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Calculs de fréquences 253

telles valeurs se fait par défaut avec une dizaine de décimales, ce qui n’est ni utile niergonomique.

La fonctionsprintf permet de formater cette valeur pour l’affichage, ici avec uni-quement deux décimales. La première chaîne passée en paramètre (%.2f ) indique quela valeur affichée est un nombre réel (f pourfloat) avec au maximum deux décimales(.2 ). De plus, cette fonction permet, si le programme est localisé, d’utiliser le carac-tère de séparation des décimales correspondant à la langue.Ainsi, une localisation enfrançais permet d’obtenir en sortie des nombres décimaux utilisant la virgule et non lepoint (norme anglo-saxonne par défaut).

REMARQUE 1.– La fonctionlog de Perl donne le logarithme népérien, et non pas lelogarithme en base 2. Pour obtenir ce dernier, il suffit d’unesimple division de cettevaleur par le logarithme népérien de 2.

REMARQUE 2.– Une alternative à la multiplication des structures de données utiliséesdans ce programme serait de définir une fonction qui calcule l’information mutuelleentre deux lemmes. Le code utilisant cette version est très similaire à celui présenté :il suffirait de remplacer la boucle de calcul de l’information mutuelle par une fonctionqui serait appelée lors du tri des cooccurrents. Par contre,le mécanisme interne dutri est tel que cette fonction serait appelée un très grand nombre de fois, c’est-à-direplus d’une fois pour chaque couple en cooccurrence, ce qui impliquerait une répétitioninutile du même calcul. L’intérêt de l’utilisation d’une structure de données est doncpurement lié au temps de calcul global du programme.

Page 246: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

254

Page 247: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

CHAPITRE 7

Concordances

7.1. Principes de fonctionnement

Un concordancier est un programme simple d’exploration de corpus qui permetd’observer les contextes d’utilisation d’une unité lexicale (ou d’un ensemble d’unités)appeléepivot. La présentation des contextes d’un pivot s’appelle uneconcordance.Les concordances permettent de synthétiser rapidement leurs contextes d’utilisationlexicaux ou syntaxiques des pivots.

Un concordancier doit donc permettre à l’utilisateur de décrire très librement(c’est-à-dire avec un pouvoir d’expression maximal) les unités auxquelles il s’inté-resse. Le programme doit ensuite effectuer la recherche de ces unités dans un fichierde texte. Puis il doit afficher les résultats de façon ergonomique, notamment en per-mettant un tri des différents contextes paramétrable par l’utilisateur.

La figure 7.1 de la page 256 présente quelques lignes de la concordance du motcoupdansLes Contes de la Bécasse. Comme on peut le voir, le motcoup, en tantque pivot, est présenté dans la colonne centrale d’un tableau à trois colonnes. Chaqueligne correspond à un extrait du contexte immédiat d’une de ses occurrences. Leslignes de la concordance sont regroupées dans cet exemple ense basant sur le motsitué immédiatement à gauche, en suivant l’ordre lexicographique (à, sur, un). Cetteprésentation met en évidence deux locutions basées sur le mot coup: tout à coupetcoup sur coup. On peut également repérer la série de syntagmescoup de feu, coupde poinget coup d’épée, mais ceux-ci sont éparpillés à différents endroits de la liste.La régularité de ces expressions apparaîtrait plus clairement si le tri s’effectuait sur ledeuxième mot à droite du pivot. Le même phénomène se produit àgauche, avec desexpressions commeboire un coup.

255

Page 248: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

256 Perl pour les linguistes

Tout à coup ils s’arrêtèrent, ils avus." Et voilà que tout à coup mon compagnon, mon ami,nd le vieux garde tout à coup fit un bond de sa chaiserire en lui-même. Tout à coup , il éclata : "Ah ! vouslaient frémir, et tout à coup , brisant les branches, c

Tout à coup , la fenêtre étant restéemot, entonnait coup sur coup des lampées de cognac.la replongeait coup sur coup dans le ventre, dans l’e

ui descendaient coup sur coup dans l’estomac, gonflante le traversait comme un coup d’épée chaque fois qu’ilans la poitrine comme un coup de poing. Bien d’autresme, et lâcha lui-même un coup de feu en gambadant commans l’oreiller, quand un coup de feu retentit au loin,

nous mettons à boire un coup , et puis encore un coup,coup, et puis encore un coup , sans s’ rassasier (on eil nous ramena boire un coup .

Allons, buvons encore un coup . Avec des amis y n’ fautas. Antoine alors eut un coup d’audace, et, lui poussarade, il répondit par un coup de poing terrible qui fi

Figure 7.1. Extrait de la concordance decoupdansLes Contes de la Bécasse

On peut également constater que les contextes ne correspondent pas aux phrasesdans lesquelles le motcoup apparaît ; certains mots apparaissant aux extrémitésgauches et droites sont même tronqués. La présentation des concordances se fait sousla forme d’un tableau à trois colonnes de taille fixe qui contiennent respectivement unfragment du contexte droit, le pivot et un fragment du contexte gauche. Dans l’exempleci-dessus, la taille des colonnes pour les contextes est fixée arbitrairement à 25 ca-ractères. Certaines lignes ont des contextes gauches ou droits réduits, indiquant quel’occurrence correspondante se situe en début ou en fin de paragraphe ou de ligne.Dans le premier cas, pour garantir l’alignement des pivots,des espaces ont été ajoutésà gauche.

Si le principe d’un concordancier reste très simple, il est toutefois possible decomplexifier son fonctionnement. On peut notamment l’utiliser pour rechercher desformes non exactes (en se basant sur un patron morphologique, la lemmatisation oules catégories morphosyntaxiques). Il est également possible d’utiliser comme pivotles séquences de plusieurs unités lexicales.

Nous présentons ici deux concordanciers sur texte brut, permettant à l’utilisateurd’exprimer le pivot sous la forme d’un mot exact pour le premier et d’une expres-sion régulière pour le second. En plus de leur utilité pratique, ces exemples de pro-gramme permettent au lecteur de se familiariser avec la construction de programmescomplexes, (notamment l’utilisation des options).

Page 249: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Concordances 257

7.2. Concordances de formes exactes sur texte brut

Le programmeconcord-brut-simple.plpermet de construire la concordance d’unmot simple sur un texte brut. La taille des contextes et le critère de tri peuvent êtreparamétrés par l’utilisateur.

7.2.1. Programme et utilisation

Listing 7.1 – concord-brut-simple.plConcordances simples sur texte brut

1 use locale;2 use strict;3 use Getopt::Std;4

5 #Analyse des options6 our ( $opt_c, $opt_t );7 $opt_c = 20;8 getopts( "c:t:" );9 my ( $direction, $distance );

10 if ( defined ( $opt_t ) )11 if ( $opt_t =~ /^(G|D)([1-9])$/i )12 $direction = uc($1);13 $distance = $2;14 15 else 16 die "Le critère de tri doit être (G|D)[distance] !\n";17 18 19

20 #Analyse des arguments21 if ( $#ARGV != 0 ) 22 die "Usage : $0 [-c taille_contexte] [-t tri] mot\n";23 24 my $mot = quotemeta ( $ARGV[0] );25

26 #Recherche et construction des contextes27 my @contextes;28 while ( my $ligne = <STDIN> ) 29 chomp $ligne;30 $ligne =~ s/\t/ /g;31 while ( $ligne =~/\b$mot\b/ig ) 32 my ( $gauche, $droite );33 if ( length($‘) < $opt_c ) 34 $gauche = " " x ( $opt_c - length($‘) ) . $‘;35 36 else 37 $gauche = substr( $‘, length($‘) - $opt_c, $opt_c);38 39 $droite = substr ( $’, 0, $opt_c );40 push ( @contextes, $gauche."\t".$&."\t".$droite );41 42 43

44 #Tri et affichage

Page 250: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

258 Perl pour les linguistes

45 if ( defined( $opt_t ) )46 @contextes = sort47 critere_tri( $a ) cmp critere_tri( $b ) 48 @contextes;49 50 print join ( "\n", @contextes ),"\n";51

52 sub critere_tri 53 my $contexte = shift @_;54 if ( $contexte =~ /^(. * ?) ?\t. * \t ?(. * )$/ )55 my $c_gauche = $1;56 my $c_droit = $2;57 my @tab;58 if ( $direction eq "G" ) 59 @tab = reverse ( split ( / /, $c_gauche ) );60 61 else 62 @tab = split ( / /, $c_droit );63 64 if ( $#tab >= $distance - 1 )65 return $tab[$distance - 1];66 67 else 68 return "";69 70 71

Ligne de commande :perl concord-brut-simple.pl [-c taille_contexte ]

[-t critère_de_tri ] mot < fichier_texte

Exemple :perl concord-brut-simple.pl -c 25 -t G1 coup < becass2.txt

Résultat : voir figure 7.1.

Le programme lit le texte à analyser sur l’entrée standard. Le pivot lui est fournidans la ligne de commande comme argument. Le programme utilise deuxoptionspour paramétrer l’affichage des résultats (voir section 2.5, page 95 pour l’utilisationdes options). La première option (-c ) permet de préciser le nombre de caractères descontextes gauches et droits. Si l’utilisateur ne fait pas appel à cette option, c’est la taillepar défaut, 20 caractères, qui est utilisée. La seconde option -t permet d’indiquer lecritère de tri en identifiant la position par rapport au pivotdes mots sur lesquels le trilexicographique doit être effectué. La syntaxe de la valeurattendue par cette optionest la suivante : une lettre (Gou D) pour indiquer la direction (Gauche ouDroite) puisune valeur numérique pour préciser la distance du mot par rapport au pivot. Ainsi,G1

désigne le premier mot à gauche du pivot. Le deuxième mot à droite est identifié parD2, etc. Si l’option de tri n’est pas utilisée, les contextes sont présentés dans l’ordrenaturel du texte.

Page 251: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Concordances 259

7.2.2. Détails du programme

Ce programme se découpe en 3 étapes :

1) analyse et vérification des options et des arguments (lignes 5 à 24) ;

2) parcours du texte et recherche des occurrences du pivot (lignes 26 à 42) et calculdes contextes (lignes 32 à 40) ;

3) tri éventuel et affichage des contextes (lignes 44 à 50).

Le programme utilise de plus une fonctioncritere_tri pour sélectionner lesmots sur lesquels le tri doit porter (lignes 52 à 71).

7.2.2.1.Analyse des options et arguments

Ce programme dispose de deux options, qui permettent de définir la taille ducontexte et le critère de tri. La déclaration de ces options comporte trois parties :

1) le moduleGetopt::Std est invoqué en début de programme en utilisant ladirectiveuse(il s’agit d’un module standard de Perl et il n’a pas besoin d’être installé) ;

2) deux variables scalaires sont déclarées pour recevoir les valeurs des options :$opt_c pour la taille du contexte et$opt_t pour le critère de tri. Ces deux variablesont un statut particulier. Leur affectation étant réaliséeautomatiquement grâce au mo-dule Getopt::Std , elles doivent être déclarées avec le mot-cléour au lieu demy.$opt_c reçoit une valeur par défaut (ici 20) qui définit la taille du contexte quandl’option -c est absente de la ligne de commande ;

3) la fonction prédéfiniegetoptsest exécutée, avec comme paramètre une chaînede caractères qui indique le nom des options et leur nature (option simple ou optionà valeur). Cette fonction analyse la ligne de commande, affecte les variables corres-pondant aux options définies et modifie le contenu du tableau d’arguments@ARGV, detelle sorte que celui-ci ne contient plus, après son exécution, les différents élémentsqui correspondent aux options.

La chaîne de caractères qui décrit les options confiéesgetoptsest ’c:t:’ . Ellecontient le nom des options (icic et t ), suivie chacune du caractère ‘: ’ pour indiquerqu’elles introduisent une valeur. Ces valeurs sont affectées aux variables$opt_c et$opt_t . Par exemple, pour la ligne de commande suivante :

perl concord-brut-simple.pl -c 30 -t D2 coup < becass2.txt

la variable$opt_c contiendra30 et $opt_t la chaîne "D2".

En cas d’erreur sur les options, notamment lorsqu’une option non prévue est uti-lisée, un message d’avertissement est émis par l’interpréteur Perl (unknown option),mais le programme continue néanmoins.

Page 252: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

260 Perl pour les linguistes

REMARQUE.– Le traitement des arguments doit toujours être réalisé après l’appel à lafonctiongetopts. Avant l’appel, le tableauARGVcontient en effet ces arguments maisaussi les options et les valeurs destinées àgetopts.

Le mot pivot est le seul argument obligatoire deconcord-brut-simple.pl. Il est ré-cupéré dans$ARGV[0] après vérification de la présence de l’argument.

Si l’option de tri (-t ) est absente de la ligne de commande, la variable$opt_t

reste indéfinie, puisqu’elle n’a pas reçu de valeur par défaut. Si -t a été utilisé, la va-leur qui suit sur la ligne de commande est rendue disponible dans cette même variableet peut être analysée. Cette valeur doit correspondre à une syntaxe spécifique, c’est-à-dire une lettre indiquant la direction (GouDpour gauche ou droite) et un chiffre (autreque 0) indiquant la distance par rapport au pivot. Un test estdonc effectué par ex-pression régulière pour vérifier cette syntaxe : un échec de la mise en correspondanceentraîne l’arrêt du programme et l’affichage d’un message d’erreur. Si la correspon-dance réussit, on stocke dans deux variables scalaires la direction ($direction ) etla distance ($distance ) qui seront utilisées pour le tri. De plus, le code permet à l’uti-lisateur d’indiquer indifféremment la direction avec une lettre majuscule ou minuscule(grâce à l’optioni lors de la mise en correspondance). Mais cette valeur (stockée dansla variable$direction ) est convertie en majuscules par la fonctionuc pour faciliterles tests ultérieurs.

Comme la recherche des occurrences s’effectue par expression régulière, il fautpréparer le mot fourni par l’utilisateur pour que la recherche s’effectue sans pro-blèmes. En effet, si le mot contient des métacaractères (comme ‘. ’ ou ‘ ( ’, (voir listecomplète en paragraphe A5.8.1, page 487), ceux-ci doivent être échappés pour leurfaire perdre leur sens spécifique dans le contexte des expressions régulières. La fonc-tion quotemetaeffectue cette transformation. Le pivot recherché est ensuite stockédans la variable$mot .

7.2.2.2.Parcours du texte et recherche

Les données correspondant au texte analysé, lues sur l’entrée standard, sont par-courues ligne par ligne de façon classique. Toutefois, il est nécessaire de supprimerles éventuelles tabulations qui pourraient se trouver dansle texte. Comme on le verraplus loin, la tabulation est utilisée pour structurer les lignes de contexte : ce ne se-rait pas possible si des tabulations provenant des données initiales intervenaient. Lestabulations sont donc remplacées par des espaces (ligne 30).

Pour chaque ligne, le pivot indiqué par l’utilisateur est recherché par une ex-pression régulière, à l’aide d’une boucle de recherche globale (optiong), afin de nepas limiter le traitement à la première occurrence de la ligne (voir programme 4.4,page 183). L’expression régulière elle-même est constituée du mot recherché (variable$mot ) entouré de frontières de mot (\b ) pour éviter par exemple de repérerdécouper

Page 253: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Concordances 261

alors que c’estcoupqui est recherché. L’utilisation de l’optioni permet d’ignorer lesdifférences de casse lors de la mise en correspondance.

7.2.2.3.Calcul du contexte

Pour chaque occurrence repérée, le contexte à afficher est calculé, en se basant surla taille indiquée par l’utilisateur (variable$opt_c ). Ce calcul se fait en deux temps :partie gauche puis partie droite. Après la mise en correspondance de$ligne avecl’expression régulière, deux variables spéciales sont automatiquement affectées avecles parties gauche ($‘ ) et droite ($’ ) de la chaîne (voir paragraphe 4.6.2, page 182).Il suffit donc de prélever dans ces chaînes les sous-chaînes correspondant à la taillevoulue.

Pour le contexte gauche, il faut d’abord vérifier que la partie gauche disponibledans$‘ est de longueur suffisante. Si toutefois l’occurrence trouvée se situe vers ledébut de la ligne et que la partie gauche disponible n’est passuffisamment longue,il est nécessaire d’ajouter des espaces en début de chaîne pour atteindre le nombrede caractères voulu par l’utilisateur, et éviter ainsi lorsde l’affichage un décalage dupivot par rapport aux autres occurrences. Ceci se fait simplement en concaténant àgauche de la chaîne disponible un nombre d’espaces égal à la différence entre la taillevoulue et la taille disponible. Cette dernière informationest obtenue en utilisant lafonctionlength, qui calcule le nombre de caractères contenus dans une chaîne passéeen paramètre. L’opérateur binairex permet quant à lui de créer une chaîne composéedu nombre correct d’espaces. La fonction de cet opérateur est de construire une chaînepar répétition d’une séquence de caractères (opérande gauche dux) un nombre de foisindiqué à droite. Par exemple, l’expression suivante produit une chaîne composée de10 tirets :

"-" x 10

Par exemple, si la chaîne$‘ a une longueur de 12 caractères, alors que la taille decontexte voulue ($opt_c ) est de 20, il est nécessaire d’ajouter 8 espaces au début ducontexte gauche (20− 12 = 8).

Si en revanche la chaîne située à gauche est suffisamment longue, il est néces-saire d’en extraire la sous-chaîne située à l’extrémité droite de taille$opt_c . Cetteopération se fait grâce à la fonctionsubstr. Les paramètres de cette fonction sont lessuivants :

– la chaîne dont une sous-partie va être extraite, donc ici$‘ ;

– la position1 du premier caractère de$‘ qui va être retenu. Cette position estcalculée dans notre cas en soustrayant la taille du contextevoulu à la longueur totale de

1. Les caractères sont numérotés comme les éléments d’un tableau. Le premier a le numérozéro.

Page 254: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

262 Perl pour les linguistes

la chaîne$‘ . Par exemple, si$‘ contient 22 caractères et que l’on souhaite en extraireles 20 derniers, le premier caractère retenu sera le caractère numéro 2 (22− 20 = 2),laissant ainsi de côté les caractères de numéros 0 et 1 ;

– la taille de la sous-chaîne souhaitée, donc ici la taille ducontexte voulu($opt_c ).

Le résultat de cette extraction est conservé dans la variable$gauche .

Le contexte droit est plus simple à calculer, puisqu’il n’est pas nécessaire d’y ajou-ter d’espaces (les espaces en fin de ligne n’influencent pas lerésultat visible, contraire-ment à ceux qui sont ajoutés au contexte gauche). Il suffit donc de tronquer la chaîne(contenue dans$’ ) en n’en retenant que les$opt_c premiers ; ceci se fait une foisencore en utilisant la fonctionsubstr, en précisant que l’on extrait de$’ une sous-chaîne commençant par le caractère numéro zéro et de longueur $opt_c . Si toutefoisla chaîne$’ ne contient pas suffisamment de caractères, le résultat desubstr sera l’en-semble de cette chaîne, sans que cela ne déclenche d’erreur.Le contexte droit extraitest placé dans la variable$droite .

Une fois$gauche et$droite calculées, la ligne de contexte à afficher pour l’oc-currence courante est ajoutées au tableau@contextes . Elle est obtenue par la conca-ténation des éléments suivants :

– la partie gauche ($gauche ) ;

– une tabulation (\t ) ;

– le mot pivot lui-même tel qu’il a été trouvé ; il est disponible dans la variablespéciale$& en tant que partie de la ligne mise en correspondance avec l’ensemble del’expression régulière (voir paragraphe 4.6.2) ;

– une tabulation (\t ) ;

– la partie droite du contexte ($droite ).

7.2.2.4.Tri et affichage des contextes

Un tri est appliqué aux éléments du tableau@contextes avant son affichagelorsque l’utilisateur indique dans la ligne de commande queles contextes doiventêtre triés (grâce à l’option-t . Cette opération se fait en utilisant la fonctionsort,qui doit être paramétrée. La procédure de paramétrage desort est décrite en détail enparagraphe 6.2.1, page 231.

La fonctioncritere_tri extrait d’une ligne de contexte à afficher le mot surlequel le tri doit être effectué. Cette fonction reçoit en paramètre la ligne de contextetelle qu’elle a été calculée précédemment, et retourne le mot dont la position par rap-port au pivot est indiquée par les variables globales$direction et$distance .

Page 255: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Concordances 263

Par exemple, soit les deux lignes de contexte suivantes du mot coup, extraites dela figure 7.1 :

A : ans l’oreiller, quand un coup de feu retentit au loin,

B : mot, entonnait coup sur coup des lampées de cognac.

Si le critère de tri est le premier mot à gauche (G1), la fonctioncritere_tri doitextraire du contexte A le motun et du contexte B le motsur. La comparaison de cesdeux mots selon l’ordre lexicographique (opérateurcmp dans la fonctionsort) permetensuite de décider que le contexte B doit être affiché avant lecontexte A.

Une expression régulière permet d’identifier dans le contexte la partie gauche, lepivot et la partie droite en se basant sur les tabulations. Lapartie indiquée par la va-riable$direction est ensuite découpée en mots en se basant sur les espaces, puis lemot dont la position est indiquée par$distance est sélectionné et renvoyé commevaleur de retour. L’expression régulière qui effectue la mémorisation des contextesgauche et droit exclut les éventuels espaces entourant le mot pivot. De même, la pre-mière fermeture de l’expression régulière (. * ?) est rendue non gloutonne pour exclureaussi du contexte gauche ces espaces éventuels. Voir paragraphe 4.5.4 (page 178) pourplus de détails sur l’extraction de sous-chaînes par des fermetures multiples. Une foisla ligne de contexte découpée, les deux segments droit et gauche sont stockés dans lesvariables locales$c_gauche et $c_droit .

Le programme segmente ensuite en mots la partie du contexte correspondant à lavariable$direction . Cette opération est réalisée par la fonctionsplit en se basantsur les espaces : il n’est pas nécessaire d’avoir ici de la finesse d’une véritable segmen-tation d’un texte brut. Le tableau résultant (@tab) est inversé par la fonctionreversedans le cas du contexte gauche, puisque le sens de parcours est justement inversé. Lafonction reversese contente de produire, pour un tableau qui lui est donné en argu-ment, un tableau constitué des mêmes éléments, mais dans l’ordre inverse (le premierdevenant le dernier, etc.).

Le mot sur lequel porte le tri est ensuite obtenu en faisant référence au contenu dela case numéro ($distance - 1) du tableau@tab (par exemple si la distance vaut 1,le mot renvoyé est le premier du tableau, donc celui dont le numéro de case est zéro).

Par exemple, pour le contexte A ci-dessus, la partie gauche est celle qui est retenue.Sa segmentation donne un tableau@tmpà 4 éléments :

("ans", "l’oreiller,", "quand", "un")

Après inversion et repérage de l’élément numéro 0 (1 − 1 = 0), c’est bien «un » quiest renvoyé comme résultat.

REMARQUE.– Même si ce programme est conçu pour construire les concordancesde mots simples, son fonctionnement admet que la chaîne recherchée soit composée

Page 256: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

264 Perl pour les linguistes

de plusieurs mots. Par exemple, il est possible d’effectuerla recherche de la séquence« coup de», dont le résultat est donné en figure 7.2 (le tri est effectuéici sur le premiermot à droite).

Et le baron, d’un coup de doigt, faisait vivet lâcha lui-même un coup de feu en gambadant co’oreiller, quand un coup de feu retentit au loiure qu’au fracas du coup de fusil que je n’atte

la seule minute du coup de fusil sur la tête bil répondit par un coup de poing terrible qui

a poitrine comme un coup de poing. Bien d’autreoulogne, un nouveau coup de vent se déchaîna ;

Figure 7.2. Concordance decoup dedansLes Contes de la Bécasse

La seule difficulté pour obtenir ce résultat est de préciser dans la ligne de com-mande quecoup deconstitue le premier paramètre du programme. Comme cettechaîne contient un espace, il faut la placer entre guillemets doubles pour éviter quele shell ne l’interprète comme deux paramètres distincts. La ligne de commandecorrespondante est la suivante :

perl concord-brut-simple.pl -t D1 "coup de" < becass2.txt

7.3. Concordances par expressions régulières sur texte brut

La version précédente du concordancier ne permet pas d’utiliser comme objet dela recherche autre chose qu’une forme lexicale fixe. Elle n’était donc pas adaptée àl’étude des contextes d’une famille de formes, ne fut-ce qu’une simple variation denombre pour un nom ou un adjectif, comme la famille de formes adjectivalesvieux,vieil, vieille et vieillesqui sert de pivot en figure 7.3.

e la commune. C’était un vieil homme à cheveux blancs qAlors le vieux la fit taire. Et comme i

pour arbitre le docteur, vieux médecin parisien retiréLa vieille mère lavait ses tabliers

e dans son secrétaire un vieux papier, le déplia, le bar de mort, tandis que le vieux paysan, retirant son armta seul à peiner avec le vieux père pour nourrir la mère Fourville, le père, un vieux petit paysan sec et ridéec cérémonie à une toute vieille petite femme vêtue de no

levaient les bras ; des vieilles pleuraient ; un aïeul la

Figure 7.3. Extrait de la concordance devieil, vieux, vieille et vieillesdansLes Contes de la Bécasse

Page 257: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Concordances 265

La version détaillée ici permet de le faire en décrivant l’objet de la recherche àl’aide d’une expression régulière.

7.3.1. Programme et utilisation

Listing 7.2 – concord-brut-expreg.plConcordances par expressions régulières sur texte brut1 use locale;2 use strict;3 use Getopt::Std;4

5 #Analyse des options6 our ( $opt_c, $opt_t );7 $opt_c = 20;8 getopt( "c:t:" );9

10 my ( $direction, $distance );11 if ( defined ($opt_t) )12 if ( $opt_t =~ /^(G|D)([1-9])$/i )13 $direction = uc($1);14 $distance = $2;15 16 else 17 die "Le critère de tri doit être (G|D)(distance) !\n";18 19 20

21 #Analyse des arguments22 if ( $#ARGV != 0 ) 23 die "Usage : $0 [-c taille_contexte] [-t tri] expression\n" ;24 25

26 my $expression = $ARGV[0];27 eval "" =~ /$expression/ ;28 if ( $@ ne "" )29 die "Erreur dans l’expression régulière !\nDétails : ",$@, "\n";30 31

32 #Recherche et construction des contextes33 my ($max, @contextes);34 while ( my $ligne = <STDIN> ) 35 chomp $ligne;36 $ligne =~ s/\t/ /g;37 while ( $ligne =~/\b($expression)\b/ig ) 38 my ( $gauche, $droite );39 if ( length($‘) < $opt_c ) 40 $gauche = " " x ( $opt_c - length($‘) ) . $‘;41 42 else 43 $gauche = substr( $‘, length($‘) - $opt_c, $opt_c );44 45 $droite = substr ($’, 0, $opt_c );46 push ( @contextes, $gauche."\t".$&."\t".$droite );47 if ( length($&) > $max )48 $max = length($&);

Page 258: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

266 Perl pour les linguistes

49 50 51 52

53 #Normalisation des contextes54 for ( my $i = 0 ; $i <= $#contextes ; $i++ )55 if ( $contextes[$i] =~ /^(. * )\t(. * )\t(. * )$/ )56 $contextes[$i] = $1 . "\t" .57 $2.(" "x($max-length($2)))."\t".$3;58 59 60

61 #Tri et affichage62 if ( defined($opt_t) )63 @contextes = sort64 &critere_tri($a) cmp &critere_tri($b) 65 @contextes;66 67 print join ( "\n", @contextes ),"\n";68

69 sub critere_tri 70 my $contexte = shift @_;71 my ( $c_gauche, $c_droit, $pivot, @tab );72 if ( $contexte =~ /^(. * ?) ?\t(. * )\t ?(. * )$/ )73 $c_gauche = $1;74 $pivot = $2;75 $c_droit = $3;76 if ( $direction eq "G" ) 77 @tab = reverse ( split ( / /, $c_gauche ) );78 79 else 80 @tab = split ( / /, $c_droit );81 82 if ( $#tab >= $distance - 1 )83 return $tab[$distance - 1];84 85 else 86 return "";87 88 89

Ligne de commande :perl concord-brut-expreg.pl [-c taille_contexte ]

[-t critère_de_tri ] expression < fichier_texte

Exemple :perl concord-brut-expreg.pl -c 25 -t D1 "vieux|vieil(les? )?"

< becass2.txt

L’expression régulière utilisée ici permet de calculer la concordance conjointe desformesvieux, vieil, vieille et vieilles, triée en fonction du premier mot à droite. Lerésultat est celui présenté en figure 7.3.

Page 259: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Concordances 267

REMARQUE.– Il est nécessaire, pour l’utilisation de ce programme, deplacer l’ex-pression régulière entre guillemets doubles, puisqu’ellecontient certains caractèresspéciaux (voir paragraphe 2.3.2, page 90).

7.3.2. Présentation du programme

La structure générale de ce programme est identique à celle de concord-brut-simple.pl (listing 7.1). Deux traitements supplémentaires y sont toutefois ajoutés :la vérification de l’expression régulière passée en paramètre, et la normalisation deslignes de contexte.

7.3.2.1.Vérification de l’expression régulière

Cette première étape supplémentaire permet d’éviter des erreurs lors de l’exécu-tion du programme dans les cas où l’utilisateur fournit une expression régulière syn-taxiquement incorrecte. Cette vérification a donc lieu avant la recherche, et permet destopper immédiatement le programme en cas d’erreur.

La procédure de détection des erreurs de syntaxe est décriteen détails dans leparagraphe 5.2.3 (page 198).

7.3.2.2.Normalisation des contextes

La normalisation des contextes est nécessaire puisqu’à la différence du programmeprécédent, la taille du pivot peut varier d’un contexte à l’autre. Pour assurer une pré-sentation correcte en colonnes, il faut que la deuxième ait une taille fixe, à savoir lenombre de caractères du pivot le plus long. Sans cette normalisation, l’affichage decontextes de mots distincts donnerait un décalage comme celui-ci :

Elles étaient vieilles , sèches, courbées.man." Tandis que le vieux , tout tremblant, di

un doux sourire de vieille . Des haies touffues

Ce résultat est dû au fait que la tabulation ne garantit pas systématiquement unalignement identique des caractères qui la suivent. L’espace horizontal qu’elle occupedépend en effet de sa position sur la ligne. Plus précisément, une tabulation effectue un« saut » jusqu’au prochain taquet de tabulation, une position arbitrairement située tousles 8 caractères. Dans le cas ci-dessus, comme le pivotvieillespossède 8 caractères, latabulation située derrière lui est située un taquet (8 caractères) plus loin que celle quisuit les pivotsvieux(5 caractères de long, donc 3 caractères avant le prochain taquet)et vieille (7 caractères de long, donc 1 caractère avant le taquet suivant).

La solution proposée ici consiste à ajouter des espaces aux mots courts pour lescompléter à hauteur du nombre de caractères du mot le plus long. Si vieilles est leplus long, il suffit d’ajouter 3 espaces àvieuxet 2 àvieille. On obtient alors l’affichagecorrect ci-dessous :

Page 260: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

268 Perl pour les linguistes

Elles étaient vieilles , sèches, courbées.man." Tandis que le vieux , tout tremblant, di

un doux sourire de vieille . Des haies touffues

L’uniformisation de la taille de la deuxième colonne se faiten deux temps. Lorsde la recherche des occurrences, la taille du mot le plus longest calculée et stockéedans la variable$max. Puis, une fois toutes les lignes de contexte à afficher obtenues,celles-ci sont modifiées en y ajoutant les espaces manquants.

Le calcul du pivot le plus long se fait au fil de la recherche parune méthode decalcul de maximum très classique en algorithmique qui ne nécessite qu’un test simple.On compare la taille de chaque nouvelle occurrence avec celle stockée dans la variable$max. Si la nouvelle occurrence est plus longue, sa longueur devient le nouveau maxi-mum et est stockée dans$max. A la fin de la boucle de recherche,$max contient lenombre de caractères de l’occurrence la plus longue.

Une fois cette valeur connue, les contextes stockés dans le tableau@contextes

sont parcourus par une boucle (ici une bouclefor ) pour ajouter à la suite du pivot unnombre d’espaces égal à la différence entre la longueur du mot le plus long ($max) etcelle du pivot considéré. L’opérateurx permet d’obtenir facilement la chaîne compo-sée du nombre d’espaces requis.

Une fois les contextes normalisés, leur tri et leur affichagese font de la mêmefaçon que pourconcord-brut-simple.pl, la fonctioncritere_tri étant strictementidentique dans les deux programmes.

7.4. Autres types de concordancier

Il est tout à fait possible d’étendre la notion de concordance à tout type d’unité re-cherchée et de données textuelles. Il est par exemple possible d’appliquer les méthodesdécrites ci-dessus à des textes segmentés, lemmatisés ou catégorisés, et d’utiliser desprocédures de recherche aussi variées que celles présentées dans le chapitre 5. La no-tion de concordance n’intervient de fait qu’à la fin de la recherche, et ne concerne aubout du compte que l’affichage des résultats.

Page 261: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

CHAPITRE 8

Traitements lexicaux

Les lexiques interviennent dans de très nombreux traitements de données linguis-tiques. Il en existe de deux types. Les lexiques issus de dictionnaires sont des sourcesde connaissance contrôlées qui listent une portion significative des mots de la langue.Mais les lexiques peuvent aussi être créés à partir des textes en compilant leurs voca-bulaires. C’est par exemple en comparant ces deux types de listes que l’on repère lesmots « inconnus » qui apparaissent dans un texte ou dans un corpus textuel.

Les lexiques sont des ressources primaires pour certaines études, notamment enmorphologie. La description d’un suffixe dérivationnel comme -ité peut par exempleêtre appuyée sur un lexique commeMorphalouqui permet de constituer un corpus de1 033 noms ayant cette finale (voir section 8.1). Mais les lexiques peuvent aussi êtredes ressources auxiliaires. Un linguiste qui s’intéresse par exemple aux complémentsdes prédicats nominaux peut extraire d’un lexique commeVerbactionune liste denoms d’action puis l’utiliser pour repérer des contextes dans lesquels ils sont suivis decompléments (voir chapitres 1 et 7).

Ce chapitre présente un ensemble de traitements portant surles lexiques ou danslesquels ces derniers ont un rôle central. Les programmes proposés couvrent une pa-lette de besoins assez large, au premier rang desquels on trouve la création et l’amé-lioration des ressources lexicales elles-mêmes :

– l’extraction de sous-lexiques destinés à l’étude des affixes dérivationnels et desparadigmes flexionnels ;

– la caractérisation globale de lexiques permettant par exemple de les présentersommairement ;

– la création de lexiques de grande taille par fusion de plusieurs lexiques pluspetits ;

269

Page 262: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

270 Perl pour les linguistes

– le repérage des éventuelles erreurs contenues dans un lexique particulier en lecomparant à d’autres ressources lexicales ;

– le recensement de données pour l’étude de la flexion verbaleen identifiant les pa-radigmes défectifs. Ces exceptions permettent aussi de repérer certaines erreurs conte-nues dans la ressource ;

– la création d’un dictionnaire de rimes à partir d’un lexique comportant des des-criptions phonologiques.

Les lexiques sont aussi utilisés comme référence pour d’autres tâches comme :

– l’identification des néologismes contenus dans un corpus textuel ;

– la catégorisation des mots inconnus par exemple pour permettre la sélection deceux qui sont pertinents une étude particulière.

Ce sont des sources de connaissances importantes pour les recherches systéma-tiques dans les grands corpus ou sur le Web. Les lexiques servent de données et demodèles pour produire des requêtes, notamment pour :

– l’énumération des instances fléchies d’une construction syntagmatique ;

– le calcul des formes fléchies d’un néologisme pour en rechercher d’autres attes-tations ;

– la génération des dérivés construits par un préfixe commein- ou un suffixecomme-ité à partir d’un mot quelconque de la langue.

Les résultats des deux dernières tâches ne sont pas totalement fiables. Ces motssont en effet produits mécaniquement par des programmes quin’ont accès qu’à desinformations relativement pauvres et qui utilisent des approximations. Les erreurs sontprincipalement induites par ces approximations. Ce sont des monstres, c’est-à-dire desformes qui ne respectent pas les règles de la phonologie, de l’orthographe ou de lamorphologie du français ou des mots qui n’existent pas pour des raisons lexicales ousémantiques. Mais certaines de ces erreurs sont aussi commises par les locuteurs de lalangue et peuvent même être entrées dans l’usage. Ainsi, selon l’utilisation finale desrésultats de ces programmes, elles doivent être éliminées par une révision manuelleou conservées.

Les ressources lexicales servent aussi à tester des modélisations de phénomèneslinguistiques et notamment morphologiques. Elles permettent d’appliquer à unegrande échelle des règles d’analyse et de génération et ainsi de vérifier la couvertureet la validité des modèles. L’accent n’est pas mis ici sur ce type d’utilisation, mêmesi des programmes comme 8.13 et 8.14 peuvent être directement exploités dans cetteperspective.

Page 263: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Traitements lexicaux 271

Les traitements présentés dans ce chapitre sont tous réalisés sur des lexiques enformat tabulé (voir paragraphe 1.5.2 page 63 pour une liste de telles ressources). L’uti-lisation de lexiques en XML est néanmoins possible mais doitêtre réalisée au moyendes modules spécialisés présentés dans le chapitre 9. Les programmes de manipu-lation de données en XML (voir paragraphe 9.2.2.1 page 333) peuvent ainsi servirde socle pour implémenter les traitements lexicaux décritsdans la suite de ce cha-pitre. Une autre solution consiste à traduire ces ressources dans un format tabulé plussimple (voir paragraphe 2.7.7 page 110) que l’on peut ensuite exploiter directementpar les programmes présentés ci-dessous. Rappelons que dans ce format, chaque lignedu fichier décrit une entrée qui se compose de trois informations séparées par destabulations : la forme, le lemme et la catégorie. L’exemple suivant présente les deuxentrées de la formeavions(nom commun masculin pluriel ; verbe indicatif imparfait1re personne du pluriel) :

avions avion Ncmpavions avoir Vmii1p-

8.1. Extraire un sous-lexique

L’opération la plus simple que l’on peut réaliser sur un lexique est d’en extraireun sous-lexique destiné à une étude particulière. Cette opération est une instance dela recherche d’unités linguistiques présentée dans le chapitre 5. Par exemple, l’ex-traction d’un lexique de noms en-ité ou -etéà partir du lexiquemorphalou.txt1, estpratiquement identique à la recherche des adjectifs en-abledans un texte catégorisé.Le programmenoms-ite.plest une adaptation deadjectifs-able.pl(programme 5.6)détaillé en paragraphe 5.3.2.1, page 205).

Listing 8.1 – noms-ite.plExtraction des noms en-etéet -ité du lexiqueMorphalou

1 use strict;2 use locale;3 while(my $ligne = <STDIN>)4 chomp($ligne);5 if ($ligne =~ /. * \t(. * [ei]té)\tNcfs$/)6 print $1, "\n";7 8

Ligne de commande :perl noms-ite.pl < lexique

1. Rappelons que ce lexique est une version deMorphalou traduite dans le format GRACE(voir paragraphe 2.7.7 page 110). Le jeu d’étiquettes GRACEest détaillé en paragraphe 1.5.2.8,page 70.

Page 264: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

272 Perl pour les linguistes

Exemple :perl noms-ite.pl < C:\PPL\Lexiques\morphalou.txt

Les exemples de ligne de commande proposés dans ce chapitre sont destinés ausystème Windows. La version adaptée au système Unix peut être obtenue en rempla-çant dans les chemins les barres obliques arrières (\) par des barres obliques avant (/)et en modifiant la localisation du répertoirePPL (~/PPL). Par exemple, le chemin dulexiqueMorphaloudevient~/PPL/Lexiques/morphalou.txt.

Résultat (extrait) :

absoluitéabsorptivitéabstractivitéabsurditéacceptabilitéaccessibilitéaccidentalité

Ce programme affiche les lemmes qui se terminent pareté (ancienneté) ou ité(capacité) et dont la catégorie estNcfs (nom commun féminin singulier).

Une autre variante deadjectifs-able.plpermet d’extraire les noms d’action dulexiqueverbaction.txt(voir paragraphe 1.5.2.6). Le programme qui réalise cette ex-traction est presque identique au précédent. Seule la ligne5 qui doit être remplacéepar :

if ($ligne =~ /. * \/. * \t(. * )\/Nc..$/)

Ces exemples montrent clairement que l’extraction de sous-lexiques implique sim-plement l’adaptation au format du lexique de l’expression régulière qui analyse lesentrées.

8.2. Caractérisation globalement d’un lexique

Une manière simple de comparer des lexiques ou des textes se fait en utilisant dessignatures, c’est-à-dire un ensemble de propriétés qui caractérisent la ressource ou ledocument. Par exemple, on peut décrire un lexique par le nombre de ses entrées, de sesformes, de ses couples lemmes/catégories, par le nombre moyen d’entrées par lemme,etc. Le programme suivant permet de calculer les valeurs de ces propriétés :

Page 265: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Traitements lexicaux 273

Listing 8.2 – caracterisation-lexique.plCaractérisation quantitative d’un lexique

1 use strict;2 use locale;3 my $entrees;4 my %formes;5 my %cats;6 my %lemmes;7 while (my $ligne = <STDIN>)8 chomp($ligne);9 my ($forme, $lemme, $cat) = split(/\t/, $ligne);

10 $entrees ++;11 $formes$forme = 1;12 $cats$cat = 1;13 $lemmes$lemme . "\t" . substr($cat, 0, 1) = 1;14 15 print "entrées : ", $entrees, "\n";16 my @cles_formes = keys %formes;17 print "formes : ", $#cles_formes + 1, "\n";18 my @cles_lemmes = keys %lemmes;19 print "lemmes : ", $#cles_lemmes + 1, "\n";20 my @cles_cats = keys %cats;21 print "catégories : ", $#cles_cats + 1, "\n";22 print "ratio entrées/lemmes : ",23 sprintf ("%.2f", $entrees / ($#cles_lemmes + 1)), "\n";

Ligne de commande :perl caracterisation-lexique.pl < lexique

Exemple 1 :perl caracterisation-lexique.pl < C:\PPL\Lexiques\morp halou.txt

Résultat :

entrées : 524725formes : 384848lemmes : 65532catégories : 64ratio entrées/lemmes : 8.01

Exemple 2 :perl caracterisation-lexique.pl < C:\PPL\Lexiques\leff f-grace.txt

Résultat :

entrées : 569858formes : 351020lemmes : 56744catégories : 114ratio entrées/lemmes : 10.04

Page 266: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

274 Perl pour les linguistes

Détails du programme :

Ce programme maintient un compteur et trois structures de données au fur et àmesure de la lecture du lexique (lignes 7 à 15) :

1) la variable scalaire$entrees pour le nombre d’entrées (ligne 10) ;

2) le hachage%formes pour la liste des formes (ligne 11) ;

3) le hachage%cats pour la liste des catégories munies de leurs traits morphosyn-taxiques (ligne 12) ;

4) le hachage%lemmes pour la liste des couples lemmes/catégorie (ligne 13).Deux lemmes qui appartiennent à deux catégories différentes sont donc considéréscomme différents. Les clés du hachage%lemmes sont ainsi constituées de la formedu lemme$lemme et de la catégorie proprement dite. Cette dernière est représentéepar le premier caractère de l’étiquette, par exempleV pour les verbes, est extraite aumoyen de la fonctionsubstr. Les valeurs du hachage n’étant pas utilisées, elles sontarbitrairement fixées à 1.

Dans la deuxième partie (16 à 23), le programme affiche le nombre des en-trées (ligne 16). Il calcule et affiche ensuite les nombres declés des hachages%formes , %cats et %lemmes. Ces clés sont respectivement stockées dans les listes@cles_formes , @cles_cats et @cles_lemmes (lignes 17, 19 et 21). Le nombrefourni par l’opérateur$# doit être augmenté de 1 pour prendre en compte le fait queles éléments de la liste sont numérotés à partir de 0. La dernière ligne du programmecalcule et affiche le nombre moyen d’entrées par lemme en divisant le nombre d’en-trées par celui des lemmes. Le résultat est formaté au moyen de la fonctionsprintfafin de limiter à 2 le nombre des décimales présentées.

Caractérisation d’un texte catégorisé :

Le programmecaracterisation-lexique.plpeut être utilisé aussi pour caractériserdes textes étiquetés parTreeTaggeren l’adaptant au format de ces données. Les mo-difications à apporter sont :

– le remplacement de la ligne 9 par :

my ($forme, $cat, $lemme) = split(/\t/, $ligne);

pour prendre en compte la différence de format. Dans les textes catégorisés par leTreeTagger, les étiquettes et les lemmes sont inversés par rapports au format GRACE ;

– le remplacement de la ligne 13 par :

$cat =~ s/:. * //;$lemmes$lemme . "\t" . $cat = 1;

La substitution simplifie les étiquettes en supprimant les éventuels attributsqu’elles contiennent. Par exemple,VER:pres (verbe conjugué au présent) est réduitenVER(verbe).

Page 267: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Traitements lexicaux 275

La version modifiée du programme est fournie dans le répertoire correspondant auchapitre (caracterisation-texte.pl).

8.3. Fusion de lexiques

La qualité d’un lexique dépend de plusieurs facteurs dont son homogénéité, le tauxd’erreurs qu’il contient et sa couverture. Cette dernière caractéristique est essentiellepour de nombreuses utilisations. Une manière simple de construire des lexiques degrande taille consiste à en réunir plusieurs. On peut par exemple construire un lexiquede taille sensiblement plus grande queMorphalouet Lefff en les fusionnant. Le ta-bleau suivant présente les nombres d’entrées et de formes dechacun et du résultat deleur fusion.

Lexique Entrées FormesMorphalou 524 725 384 848Lefff 569 858 351 020Morphalou∪ Lefff 612 887 441 943

Ces chiffres sont obtenus à partir des versions converties au format GRACE de ceslexiques. Ils peuvent être calculés en utilisant des versions adaptées du programmecaracterisation-lexique.plde la section précédente.

8.3.1. Fusion simple

La fusion de deux lexiques est une opération simple qui n’implique pas d’arbi-trage. En effet, il suffit d’ajouter les entrées de l’un à celles de l’autre pour créer uneressource cohérente que satisfait les critères cumulés desdeux lexiques initiaux. Cepoint peut être illustré par les entrées relatives au nomabdominauxdansMorpha-lou et dans Lefff. Morphaloucontient les entrées suivantes pour l’adjectif nominaliséabdominal:

abdominal abdominal Ncmsabdominaux abdominal Ncmp

Lefff ne contient pour sa part pas de nom singulierabdominalmais seulement la formeau pluriel considérée comme invariable :

abdominaux abdominaux Ncmp

Page 268: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

276 Perl pour les linguistes

Le lexique fusionné contiendra ainsi les trois entrées :

abdominal abdominal Ncmsabdominaux abdominal Ncmpabdominaux abdominaux Ncmp

abdominauxy sera à la fois la forme du nom pluriel invariableabdominauxet du nomrégulierabdominal.

La seule difficulté posée par la fusion est de ne pas répéter les entrées communesaux deux lexiques.

Listing 8.3 – fusion-lexiques.plFusion de deux lexiques au même format

1 use strict;2 use locale;3 if ($#ARGV != 1)4 die "Usage : ", $0, " LEXIQUE1 LEXIQUE2\n";5 6 my %lex ;7 lire_lex($ARGV[0]);8 lire_lex($ARGV[1]);9 foreach my $entree (keys %lex)

10 print $entree, "\n";11 12 sub lire_lex13 my ($fichier) = @_;14 open(LEX, "<", $fichier) or

die "impossible d’ouvrir ", $fichier;15 while (my $ligne = <LEX>)16 chomp($ligne);17 $lex$ligne = 1;18 19 close(LEX);20

Ligne de commande :perl fusion-lexiques.pl lexique1 lexique2

Exemple :perl fusion-lexiques.pl C:\PPL\Lexiques\morphalou.txt

C:\PPL\Lexiques\lefff-grace.txt

Résultat (extrait) :

avalées avaler Vmps-pfhypersoniques hypersonique Afpfpcoxalgies coxalgie Ncfppatafiolerais patafioler Vmcp1s-

Page 269: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Traitements lexicaux 277

incurie incurie Ncfsfichiez ficher Vmii2p-petites petit Afpfpdésabuserez désabuser Vmif2p-

Détails du programme :

La fusion des deux lexiques est effectuée en stockant leurs entrées complètescomme des clés du même hachage%lex . Leurs entrées communes sont ainsi représen-tées par la même clé. Les valeurs associées aux clés ne sont pas utilisées : toutes ont lamême valeur arbitraire 1. Le lexique résultant n’est pas trié car le recours à la fonctionsort par défaut pour des données de la taille deMorphalouou de Lefff nécessite unespace mémoire trop important.

Le traitement comporte trois étapes. Les deux premières étant strictement iden-tiques, le code correspondant est factorisé dans le sous-programmelire_lex qui litles lignes d’un fichier et les stocke telles quelles comme clés du hachage%lex . Cedernier est une structure de données globale déclarée au niveau du programme princi-pal. Dans la dernière partie du traitement, les clés du hachage%lex sont rassembléesen utilisant la fonctionkeys(ligne 10) et affichées sur la sortie standard (ligne 11).

8.3.2. Fusion avec tri

Il est cependant possible de réaliser une fusion dont le résultat serait trié. La va-riante suivante du programme précédent permet de construire cette ressource.

Listing 8.4 – fusion-tri-lexiques.plFusion de deux lexiques au format GRACE puis tri des entrées du lexique résultat

1 use strict;2 use locale;3 no sort ’stable’;4 if ($#ARGV != 1) 5 die "Usage : ", $0, " LEXIQUE1 LEXIQUE2\n";6 7 my %lex;8 lire_lex($ARGV[0]);9 lire_lex($ARGV[1]);

10 foreach my $f (sort keys %lex)11 foreach my $l ( sort keys %$lex$f)12 foreach my $c (sort keys %$lex$f$l)13 print join($f . "\t" . $l . "\t" . $c), "\n";14 15 16 17 sub lire_lex18 my ($fichier) = @_;

Page 270: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

278 Perl pour les linguistes

19 open(LEX, "<", $fichier) ordie "impossible d’ouvrir ", $fichier;

20 while (my $ligne = <LEX>)21 chomp($ligne);22 my ($forme, $lemme, $cat) = split(/\t/, $ligne);23 $lex$forme$lemme$cat = 1;24 25 close(LEX);26

Ligne de commande :perl fusion-tri-lexiques.pl lexique1 lexique2

Exemple :perl fusion-tri-lexiques.pl C:\PPL\Lexiques\morphalou .txt

C:\PPL\Lexiques\lefff-grace.txt

Résultat (extrait) :

couvées couvé Afpfpcouvées couvée Ncfpcouvées couver Vmps-pfcouvent couvent Ncmscouvent couver Vmip3p-couvent couver Vmsp3p-

Détails du programme :

Cette version diffère de la précédente sur deux points : dansle sous-programmelire_lex , les entrées des lexiques fusionnés sont analysées (lignes23 et 24) et lesenregistrements sont ensuite triés (lignes 11 à 17). Les trois informations qui les com-posent sont conservées sous forme de clés du hachage%lex qui a ici trois niveaux(c’est-à-dire%lex est un hachage de hachage de hachage ; voir annexe A4). On peutillustrer graphiquement la partie de la structure de données correspondant aux résultatsprésentés dans l’extrait ci-dessus de la manière suivante :

%lex =

...

couvees⇒

couve⇒

Afpfp⇒ 1couvee⇒

Ncfp⇒ 1couver⇒

Vmps−pf⇒ 1

couvent⇒

couvent⇒

Ncfs⇒ 1

couver⇒

Vmip3p−⇒ 1Vmsp3p−⇒ 1

...

Page 271: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Traitements lexicaux 279

Comme le montre ce schéma, les clés du hachage%lex sont les formes du lexiquecommecouvéesou couvent. Les valeurs qui leur sont associées sont des référencesà des hachages « anonymes2 » (voir annexe A4 pour une présentation détaillée desréférences). Les hachages de deuxième niveau ont comme clésles lemmes des formes(commecouvéoucouver) et comme valeur des références à des hachages de troisièmeniveau. Ces derniers ont comme clés les catégories (commeAfpfp ou Vmps-pf ) etcomme valeur l’entier 1 (valeur arbitraire qui n’est pas utilisée).

Ce type de stockage permet d’éliminer les doublons localement à niveau de chaquehachage et par suite globalement au niveau du lexique dans satotalité. Il permetd’autre part de stocker de façon disjointe les trois types d’information présentes dansles entrées et de les trier séparément afin d’éviter le problème signalé en paragraphe6.2.2 (page 233) provenant du fait que la fonctionsort ignore les caractères sépara-teurs (non alpha-numériques) qui se trouvent dans les chaînes à ordonner. La solutionproposée dans le programmefrequences-formes-categories.pl(chapitre 6) ne convientpas pour le tri d’un nombre important d’éléments car elle implique de répéter l’analysedes entrées pour chaque comparaison. La solution implémentée dans le programmefusion-tri-lexiques.plsélectionne un algorithme de tri plus efficace que l’algorithmepar défaut en recourant à la directiveno sort ’stable’ (ligne 4) qui est spécifiqueà Perl 5.8. L’utilisation de cette directive n’est pas nécessaire sous Unix.

La construction du lexique final se fait en triant successivement les formes puisles lemmes associés à chaque forme et enfin les catégories correspondant à chaquecouple forme/lemme. Les formes du lexique sont fournies parla fonctionkeys quiprend comme paramètre le hachage%lex (ligne 11). La liste de ces clés est ensuitetriée par la fonctionsort avant d’être parcourue dans une bouclefor . Le programmeaccède alors au hachage de niveau 2 associé à chaque forme. Cehachage est cité enutilisant la notation%$lex f où f est une clé de%lex , c’est-à-dire une forme.Cette expression se compose de l’opérateur de déréférencement de hachage%...

appliqué à la référence de hachage$lex f . Par exemple,%$lex"couvent"

permet d’accéder au hachage de niveau 2 associé à la formecouvent. Les lemmesassociées à la formef sont les clés de%$lex f dont la liste triée est créée enfaisant successivement appel àkeyset àsort (ligne 12). La même opération est répétéeune troisième fois pour les catégories, clés des hachages%$lex f l où l est unlemme associé à la formef .

8.4. Comparaison de lexiques

Si la fusion de deux lexiques est une opération simple, le calcul de leur inter-section est relativement difficile dans la mesure où les critères de catégorisation et

2. Ces hachages sont dits anonymes parce qu’aucun identificateur ne leur est associé.

Page 272: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

280 Perl pour les linguistes

de flexion / lemmatisation varient d’une ressource à l’autre. La solution la plus immé-diate qui consiste à limiter cette intersection aux entréestotalement identiques (mêmesformes, mêmes lemmes et mêmes catégories) produit un lexique incomplet dans le-quel certains lemmes ne disposeraient que d’une partie de leurs formes fléchies. Parexemple, dans une telle intersection des lexiquesMorphalouet Lefff, l’adjectif fumeurn’aura que ses formes au masculin car les formes féminines nesont pas rattachéesaux mêmes lemmes dans les deux lexiques (le lemme defumeuseest fumeusedansMorphalouet fumeurdans Lefff ).

La meilleure solution consiste à comparer les lexiques relativement aux différentséléments qui composent les entrées : les entrées complètes,les formes, les lemmes,les couples formes/catégories, lemmes/catégories, etc. La comparaison doit se fairerelativement à l’un de ces éléments. Par exemple, le programme qui suit permet com-parer un lexique donnéL à un lexique de référenceR en se basant uniquement sur lesformes. Trois niveaux de différence sont considérés :

– les formes deL absentes deR sont marquées 1 ;

– les formes communes àL et R mais ayant des catégories différentes sont mar-quées 2. Les catégories deL à l’origine de la différence sont aussi affichées ;

– les formes communes àL et R qui y ont les mêmes catégories, mais avec deslemmes différents sont marquées 3. Dans ce cas, le programmeaffiche la forme, lacatégorie et le lemme dansL.

Ce programme n’identifie pas les entrées qui manquent àL. Elles peuvent êtreobtenues en utilisant le même programme, mais en intervertissant, lors de l’appel, leslexiquesL etR.

Listing 8.5 – comparaison-lexiques-formes.plComparaison de deux lexiques au format GRACE relativement aux formes, aux caté-gories et aux lemmes

1 use strict;2 use locale;3 if ($#ARGV != 1)4 die "Usage : ", $0, " LEXIQUE_REFERENCE LEXIQUE\n";5 6 my %lex1 = %lire_lex($ARGV[0]);7 my %lex2 = %lire_lex($ARGV[1]);8 foreach my $f (keys %lex2)9 if (not defined($lex1$f))

10 print "1\t", $f, "\n";11 12 else13 foreach my $c (keys %$lex2$f)14 if (not defined($lex1$f$c))15 print "2\t", $f, "\t", $c, "\n";16 17 else

Page 273: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Traitements lexicaux 281

18 foreach my $l (keys %$lex2$f$c)19 if (not defined($lex1$f$c$l))20 print "3\t", $f, "\t", $c, "\t", $l, "\n";21 22 23 24 25 26 27 sub lire_lex28 my ($fichier) = @_;29 my %lex;30 open(LEX, "<", $fichier) or

die "impossible d’ouvrir ", $fichier;31 while (my $ligne = <LEX>)32 chomp($ligne);33 my ($forme, $lemme, $cat) = split(/\t/, $ligne);34 $lex$forme$cat$lemme = 1;35 36 close(LEX);37 return(\%lex);38

Ligne de commande :perl comparaison-lexiques-formes.pl lexique_de_référence

lexique

Exemple :perl comparaison-lexiques-formes.pl C:\PPL\Lexiques\m orphalou.txt

C:\PPL\Lexiques\lefff-grace.txt

Résultat (extrait) :

1 prépositionnât1 cocontractant3 chanteuses Ncfp chanteur3 convainquissions Vmsi1p- convainqure2 parabolique Ncfs1 mexicanisé1 déscolarisé1 zappette

Détails du programme :

Le programme se compose de deux parties. Dans la première, les deux lexiquessont lus tour à tour au moyen de la fonctionlire_lex et stockés dans deux hachagesà trois niveaux%lex1 et %lex2 (lignes 6 et 7).lire_lex reçoit en argument le nomdu fichier qui contient le lexique (resp.$ARGV[0] et $ARGV[1] ) et retourne la réfé-rence du hachage dans lequel les entrées analysées ont été stockées. Cette analyse estidentique à celle qui est réalisée dansfusion-tri-lexiques.pl; les trois informations qui

Page 274: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

282 Perl pour les linguistes

les composent sont enregistrées séparement comme clés du hachage dont%lex . Unefois que l’ensemble de entrées sont lues, la fonction retourne la référence\%lex duhachage%lex (ligne 37).

L’ordre des clés de%lex1 et%lex2 est différent de celui qui est utilisé dansfusion-tri-lexiques.pl. Il est en effet déterminé par la manière dont ces informations sont ex-ploitées dans la deuxième partie du programme (ligne 8 à 26) où sont comparés tourà tour 1) les formes puis ; 2) les couples formes/catégories pour les formes présentesdans les deux lexiques ; 3) les triplets formes/catégories/lemmes. La comparaison estréalisée en utilisant la fonctiondefined qui permet de savoir s’il existe dans un ha-chage une information associée à une clé donnée. Ainsi, l’absence d’une clé$f dansle hachage%lex1 est vérifiée par la condition de la ligne 9 oùnot est l’opérateur denégation booléenne. Il en va de même pour les clés de 2e et 3e niveaux en lignes 14et 19.

Pour réaliser une comparaison basée sur les lemmes, il suffitd’intervertir les clésdes lemmes et des formes dans le programme précédent et de comparer les catégoriesen ignorant les autres traits morphosyntaxiques. Ce programme est disponible dans lerépertoire correspondant au chapitre (comparaison-lexiques-lemmes.pl).

8.5. Identification des verbes défectifs

Dans le cadre d’une étude sur la conjugaison en français, on peut rechercher dansun lexique commeMorphaloules verbes qui n’ont pas de formes pour certaines per-sonnes, temps ou mode (commeplairequi n’a par exemple pas de participe passé ni auféminin ni au pluriel) ou bien qui en ont plusieurs (commeje paye/ je paie). L’iden-tification de ces verbes se fait en deux temps. Il faut d’abordcalculer pour chaqueverbe la valeur de la propriété sur laquelle porte le critèred’extraction, en l’occur-rence le nombre de ses formes pour chaque étiquette (c’est-à-dire configuration mor-phosyntaxique). On peut ensuite repérer les verbes dont la conjugaison est défectiveet caractériser ces exceptions (personne, temps, mode, genre et nombre).

Le programme suivant implémente cette méthode et permet de constituer une listede verbes défectifs. La liste permet aussi de découvrir certaines lacunes dans la flexiondes verbes deMorphalou-1.0.1comme l’absence de forme conjuguée à la 2e personnedu singulier du conditionnel présent (finirais) pour les verbes du 2e groupe (finir).

Le programme distingue les verbes pour lesquels il existe plusieurs formes pourune flexion donnée commepayerou agneler, des verbes archaïques commeapparoirou enquerrequi ne s’emploient qu’à l’infinitif. Les conjugaisons exceptionnelles decertains verbes peuvent aussi être marquées par des catégories particulières commeplaire dont le participe passé est invariable. Dans ce cas, c’est laprésence de la caté-gorieVmps--- qui constitue l’exception.

Page 275: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Traitements lexicaux 283

Listing 8.6 – verbes-defectifs.plRepérage des verbes défectifs dans un lexique au format GRACE

1 use strict;2 use locale;3 my %tags;4 my %verbe;5 while (my $ligne = <STDIN>)6 chomp($ligne);7 my ($forme, $lemme, $tag) = split(/\t/, $ligne);8 if ($tag =~ /^V/)9 $verbe$lemme$tag ++;

10 $tags$tag ++;11 12 13 my @liste_verbes = sort keys %verbe;14 my (@tags_normaux, @tags_exceptionnels);15 foreach my $t (sort keys %tags) 16 if ($tags$t < 0.8 * $#liste_verbes)17 push(@tags_exceptionnels, $t);18 19 else 20 push(@tags_normaux, $t);21 22 23 foreach my $v (@liste_verbes)24 my @res;25 foreach my $t (@tags_normaux)26 if (defined($verbe$v$t))27 if ($verbe$v$t != 1)28 push(@res, $t. " " . $verbe$v$t);29 30 31 else32 push(@res, $t . " 0");33 34 35 foreach my $t (@tags_exceptionnels)36 if (defined($verbe$v$t))37 push(@res, $t . " " . $verbe$v$t);38 39 40 if (@res)41 print $v, "\t", join(" ", @res), "\n";42 43

Ligne de commande :perl verbes-defectifs.pl < lexique

Exemple :perl verbes-defectifs.pl < C:\PPL\Lexiques\morphalou.t xt

Résultat (extrait) : Les lignes qui finissent par «... » ont été tronquées.

Page 276: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

284 Perl pour les linguistes

absoudre Vmis1p- 0 Vmis1s- 0 Vmis2p- 0 Vmis2s- 0 Vmis3p- 0Vmis3s- 0 Vmsi1p- 0 Vmsi1s- 0 Vmsi2p- 0 ...

abstenir Vmcp1p- 2 Vmcp3s- 0 Vmsp1p- 0accalmir Vmcp2s- 0accroire Vmcp1p- 0 Vmcp1s- 0 Vmcp2p- 0 Vmcp2s- 0 Vmcp3p- 0

Vmcp3s- 0 Vmif1p- 0 Vmif1s- 0 Vmif2p- 0 Vmif2s- 0Vmif3p- 0 Vmif3s- 0 Vmii1p- 0 Vmii1s- 0 ...

complaire Vmps-pf 0 Vmps-pm 0 Vmps-sf 0 Vmps-sm 0 Vmps--- 1

Détails du programme :

Ce programme comporte trois parties.

Lecture du lexique, sélection des unités cibles et compilation des informations utiliséespour évaluer le critère (lignes 5 à 12). Lors de cette étape, les entrées du lexiquesont lues une à une. Les formes verbales sont sélectionnées en exploitant le fait queleurs étiquettes commencent parV. Le hachage à deux niveaux%verbe est créé aveccomme clés les lemmes et les étiquettes des entrées verbaleset comme valeur asso-ciée le nombre d’entrées dans lesquels apparaît le couple lemme/étiquette (ligne 9).Un second hachage simple%tags est créé pour mémoriser les étiquettes des formesverbales et la fréquence de chacune d’elles (ligne 10).

Identification des étiquettes exceptionnelles (lignes 13 à22). On considère commeexceptionnelles les étiquettes pour lesquelles 20 % des lemmes n’ont pas de formefléchie, ou en d’autres termes, dont la fréquence est inférieure à 80 % du nombredes verbes du lexique (ligne 16). Ce critère permet de séparer les étiquettes en deuxgroupes : celles dont la fréquence est suffisante sont ajoutées à la liste@tag_normaux

au moyen de la fonctionpush qui permet d’insérer un élément à la fin d’uneliste (ligne 17) ; celles dont la fréquence est inférieure auseuil le sont à la liste@tag_exceptionnels (ligne 20).

Le hachage%verbe ayant comme clés de premier niveau les lemmes desverbes du lexique, le nombre de ces derniers peut être calculé en créant une liste@liste_verbes des ces clés ; la taille de cette liste est alors disponible dans$#liste_verbes (ligne 16).

Identification et affichage des verbes défectifs (lignes 23 à43). Les verbes défectifssont ceux qui n’ont pas une forme et une seule pour chaque étiquette normale ou ceuxqui ont des formes associées à des étiquettes exceptionnelles. Le programme affichechacun d’eux sur une ligne séparée avec la liste des étiquettes en cause. Ces étiquettessont réunies, avec leur fréquence, dans une liste@res. Pour chaque verbe du lexique,le programme identifie :

1) les étiquettes pour lesquelles il a plusieurs formes en testant la valeur$verbe$v$t (ligne 27). Cependant ce test ne doit être réalisé que si cette va-leur est définie. C’est pourquoi il vérifie au préalable l’existence de cette valeur en

Page 277: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Traitements lexicaux 285

faisant appel à la fonctiondefined (ligne 26). L’omission de cette vérification préa-lable entraînerait l’affichage d’un avertissement pour chaque accès à%verbe par uncouple de clés indéfinies3. Si l’étiquette$t a été rencontrée plus d’une fois pour leverbe$v , $t est ajoutée avec sa valeur associée à@res ;

2) les étiquettes pour lesquelles il n’y a pas de forme (lignes 31 à 33). Dans ce cas,$verbe$v$t n’est pas défini ;

3) les étiquettes exceptionnelles pour lesquelles il a des formes (lignes 35 à 39),c’est-à-dire qui existent en tant que clés dans%$verbe$v .

Une fois rassemblées l’ensemble des étiquettes pour lesquelles le verbe est défec-tif, si la liste@res n’est pas vide, elle est affichée, précédée du lemme du verbe (ligne41). On peut noter que la liste@res est directement utilisée comme condition en ligne40. Dans un contexte booléen, la valeur retournée est VRAI sila liste n’est pas vide etFAUX sinon.

8.6. Dictionnaire de rimes

On peut très facilement créer un dictionnaire de rimes à partir d’un lexique conte-nant des descriptions phonologiques commeLexique 3. Un dictionnaire de rimes estune liste de mots ordonnée en fonction des sons par lesquels ils se terminent. Cetteliste est complétée par un index qui permet de connaître la position de chaque mot.Mais l’index n’est pas nécessaire si la liste est informatisée, les fonctionnalités derecherche dans les fichiers permettant de repérer les entrées à partir des graphies.

Pour construire une liste de formes triées en fonction des sons de leurs finales, ondoit :

1) associer à chaque forme une représentation phonologique;

2) inverser les représentations phonologiques;

3) trier lexicographiquement les représentations phonologiques inversées.

Les entrées deLexique.orgfournissent en fait une représentation phonologiqueinversée de la forme correspondante. Cette représentationse trouve en colonne 27 dansle fichierLexique3.txt4. Le tableau suivant présente quelques-unes des informationsprésentes dans ce fichier5. Les numéros des colonnes sont indiqués entre parenthèses :

3. Plus généralement, l’accès à la valeur d’une clé non définiedans un hachage complexe dé-clenche automatiquement l’ajout de cette clé. Ce comportement de l’interpréteur, appelé « auto-vivification », peut être comparé à la présupposition.4. Une copie de ce fichier est disponible dans le répertoirePPL\Lexiques(PPL/LexiquessousUnix).5. Les codes phonémiques utilisés sont décrits dans le fichierManuel_Lexique.doc.

Page 278: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

286 Perl pour les linguistes

Forme Forme Découpage Forme phonologiquegraphémique (1) phonologique (2) en syllabes (23) inversée (27)

bénévole benevol be-ne-vol lovenebbénévolement benevolm@ be-ne-vol-m@ @mlovenebfrivole fRivol fRi-vol loviRffrivolité fRivOlite fRi-vO-li-te etilOviRf

Le codage phonémique au moyen de caractères ASCII permet de manipuler etnotamment de trier les formes phonologiques comme de simples chaînes de caractères.Cependant ce tri n’est pas optimal car l’ordre des codes phonémiques est différent del’ordre lexicographique. Mais il permet d’obtenir un résultat globalement satisfaisant.Le programme suivant construit ce dictionnaire à partir deLexique3.txtpar la méthodequi vient d’être présentée.

Listing 8.7 – dictionnaire-rimes.plConstruction d’un dictionnaire de rimes à partir deLexique.org

1 use strict;2 my %lex;3 while (my $ligne = <STDIN>)4 chomp($ligne);5 my @champs = split(/\t/, $ligne);6 $lex$champs[26]$champs[0] = 1;7 8 foreach my $p (sort keys %lex)9 foreach my $f (sort keys %$lex$p)

10 print $f, "\n";11 12

Ligne de commande :perl dictionnaire-rimes.pl lexique

Exemple :perl dictionnaire-rimes.pl C:\PPL\Lexiques\Lexique3.t xt >

dictionnaire-rimes.txt

Résultat (extrait) :

aubainrobinrobinsjacobinjacobinslarbinlarbinscorbinurbainurbains

Page 279: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Traitements lexicaux 287

Détails du programme :

Ce programme extrait les formes graphémiques et leurs représentations phonolo-giques inversées puis il les trie et les affiche.

Dans la première partie (lignes 3 à 7), les entrées sont analysées en séparant leschamps de l’enregistrement dans une liste@champspuis en accédant aux éléments quiinterviennent dans le calculvia leur rang dans le tableau : la forme et la représentationphonologique inversée. Ces informations sont stockées comme clés dans un hachageà deux niveaux%lex .

Dans la deuxième partie du programme (lignes 8 à 12), les clésde premier ni-veau du hachage%lex sont triées puis utilisées pour accéder et afficher les formescorrespondantes. Le tri des représentations phonologiques inversées est réalisé sanslocalisation ; notamment les majuscules et les minuscules ne doivent pas être confon-dues car elles correspondent à des phonèmes distincts. Ce comportement est obtenuen omettant l’instructionuse locale .

8.7. Enumération des instances d’une construction syntagmatique

De nombreuses études utilisant des corpus nécessitent la recherche de construc-tions dans des textes non étiquetés ou sur le Web. Par exemple, pour collecter unensemble d’occurrences de la constructionV du bout despour un ensemble donné deverbes (regarder, manger, goûter, refuser...), il est nécessaire de créer les instancesregarde du bout des, regardent du bout des, regardé du bout des, regardait du boutdes...,mange du bout des...

Un programme capable de générer les instances d’une construction syntagmatiquepeut prendre deux formes. La plus simple est celle d’un programme spécifique à laconstruction particulière que l’on souhaite étudier. La deuxième consiste à écrire unprogramme capable de générer les instances d’une construction quelconque compor-tant une variable.

C’est cette option qui est choisie dansinstances-construction.pl. La constructionest décrite par une chaîne de caractères dans laquelle l’élément à substituer est re-présenté par sa catégorie précédée du caractère ‘§’ (ce caractère a été choisi arbitrai-rement). Par exemple,V du bout desest codée comme§V du bout des . Le pro-gramme doit en outre recevoir un lexique flexionnel et un fichier contenant la liste deslemmes à fléchir.

Page 280: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

288 Perl pour les linguistes

Listing 8.8 – instances-construction.plEnumération des instances d’une construction syntagmatique

1 use strict;2 use locale;3

4 if ($#ARGV != 1)5 die "Usage : ", $0, " CONSTRUCTION LEXIQUE_REFERENCE\n";6 7 my ($pre, $c, $post) = split(/§([A-Z])/, $ARGV[0]);8 open(LEX, "<", $ARGV[1]) or die "impossible d’ouvrir ", $AR GV[1];9 my %lex;

10 while (my $ligne = <LEX>)11 chomp($ligne);12 my ($forme, $lemme, $cat) = split(/\t/, $ligne);13 if (substr($cat, 0, 1) eq $c)14 $lex$lemme$forme = 1;15 16 17 close(LEX);18 while (my $ligne = <STDIN>)19 chomp($ligne);20 foreach my $f (keys %$lex$ligne)21 print "\"", $pre, $f, $post, "\"\n";22 23

Ligne de commande :perl instances-construction.pl construction

lexique_de_référence < liste_de_lemmes

Exemple :perl instances-construction.pl "§V du bout des"

C:\PPL\Lexiques\morphalou.txt < liste-verbes.txt

Résultat (extrait) :

"refusait du bout des""refuseras du bout des""refuserai du bout des""refuser du bout des""refusant du bout des""refuserions du bout des""refusées du bout des""refusassent du bout des""refusâmes du bout des""refuseraient du bout des""refuse du bout des"

Détails du programme :

Ce programme se compose de trois parties : l’analyse de la construction qui lui estpassée en premier paramètre, la lecture du lexique de référence indiqué par le second

Page 281: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Traitements lexicaux 289

paramètre et l’énumération des instances de la construction syntagmatique pour leséléments de la listes fournis sur l’entrée standard.

Le programme commence par décomposer en trois parties, au moyen de la fonctionsplit, la chaîne de caractères obtenue comme premier argument (ligne 7). Le sépara-teur§([A-Z]) se compose du caractère§ suivi d’une lettre majuscule Par ailleurs, lalettre est entourée de parenthèses afin d’être mémorisée. Les trois éléments issus dudécoupage de la construction sont stockés dans les variables$pre (la partie constantede la construction qui se situe avant la variable),$c (la catégorie du lemme ; c’est lapartie mémorisée du séparateur) et$post (la partie constante de la construction quise situe après la variable). Par exemple, l’analyse de la construction"§V du bout des"positionne les variables$pre , $c et $post respectivement à"" (la chaîne vide),"V"et "du bout des".

Dans la deuxième partie (lignes 8 à 17), les entrées du lexique de référence sontlues et stockées dans un hachage à deux niveaux%lex . Les étiquettes morphosyn-taxiques associées aux formes sont réduites à la catégorie grammaticale qui est repré-sentée par son premier caractère. Ce caractère est extrait en utilisant la fonctionsubstr(ligne 13). Par exemple, le programme ne retient d’une étiquette commeVmcp2s- quele V initial. Ce sont ces mêmes catégories qui doivent être utilisées pour les variablesdans les constructions (par exemple§V).

Dans sa dernière partie (lignes 18 à 23), le programme lit leslemmes pour lesquelsles instances de la construction syntagmatique doivent être générés. Une instance estainsi créée pour chaque forme du lemme en insérant cette dernière entre les partiesconstantes$pre et $post . La contrainte sur la catégorie permet d’éviter l’insertionde formes n’appartenant pas à cette dernière ; par exemple laforme nominaleallerspour le verbealler ou la forme verbaleavenantpour le nomavenir. Les instances sontentourées de guillemets afin de pouvoir être directement soumises comme requêtes àun moteur de recherche sur le Web (voir chapitre 10).

8.8. Identification des néologismes dans un texte étiqueté

Dans cette section, on considère qu’un mot est nouveau s’il est absent d’un lexiquede référence. L’identification des néologismes dans un texte étiqueté constitue ainsiune tâche semblable à la comparaison de deux lexiques, portant uniquement sur lesformes. Une comparaison plus fine faisant intervenir les catégories et les lemmes n’estpas utile car les informations du lexique de référence sont beaucoup plus fiables quecelles qui proviennent du catégoriseur et qu’un grand nombre de conversions morpho-logiques présentes dans les textes sont absentes des lexiques sans que ces emplois neconstituent à proprement parler des néologismes.

L’utilisation d’un texte étiqueté permet de limiter la recherche des néologismes auxmots des catégories « ouvertes ». Par exemple, on ne souhaitepas considérer comme

Page 282: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

290 Perl pour les linguistes

des néologismes les noms propres du texte bien qu’ils soientnormalement absents deslexiques de référence. Il en va de même des abréviations, dessigles, des signes deponctuation, etc. Seules les formes du texte catégorisées comme nom, verbe, adjec-tif ou adverbe sont donc considérées par le programmeneologismes.pl. Une difficultésupplémentaire doit être prise en compte : les nombreuses erreurs de catégorisation desnoms propres. Mais à cause de l’absence de ces noms du lexiquedu catégoriseur, leurlemme est une copie exacte de leur forme et contient donc un ouplusieurs caractèresmajuscules. On peut ainsi résoudre ce problème en limitant la collecte de néologismesaux seules formes dont les lemmes qui se composent uniquement de lettres minus-cules. Cette contrainte présente l’inconvénient d’éliminer aussi les mots composés,mais ces derniers n’étant pas décrits systématiquement dans les lexiques, il n’existepas de moyen simple de distinguer les nouveaux des anciens.

Listing 8.9 – neologismes.plDétection des néologismes contenus dans un texte catégorisé

1 use strict;2 use locale;3 if ($#ARGV != 1)4 die "Usage : ", $0, " LEXIQUE_REFERENCE TEXTE_ETIQUETE\n";5 6 open(LEX, "<", $ARGV[0]) or die "impossible d’ouvrir ", $AR GV[0];7 my %lex;8 while (my $ligne = <LEX>)9 chomp($ligne);

10 my ($forme) = split(/\t/, $ligne);11 $lex$forme = 1;12 13 close(LEX);14 open(TEXTE, "<", $ARGV[1]) or die "impossible d’ouvrir ", $ ARGV[1];15 my %ouverte = ("NOM" => 1, "VER" => 1, "ADJ" => 1, "ADV" => 1);16 my %text;17 while (my $ligne = <TEXTE>)18 chomp($ligne);19 my ($forme, $cat, $lemme) = split(/\t/, $ligne);20 $cat =~ s/:. * $//;21 if(defined($ouverte$cat) and ($lemme =~ /^\pLl+$/)) 22 $textlc($forme) = 1;23 24 25 close(TEXTE);26 foreach my $f (keys %text)27 if (not defined($lex$f))28 print $f, "\n";29 30

Ligne de commande :perl neologismes.pl lexique_de_référence texte_étiqueté

Page 283: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Traitements lexicaux 291

Exemple :perl neologismes.pl C:\PPL\Lexiques\morphalou.txt tord re1.tag

Résultat (extrait) :

capellochallanchambardoscopechatnoiresqueschemistchemistsclematiscléopâtreuxcochonicidacoincoinscolocatairescomfortableconsciuscoutumièrescrapulitecymbal

Détails du programme :

La première partie du programme (lignes 6 à 13) est identiqueau sous-programmelire_lex decomparaison-lexiques-formes.pl.neologismes.plse distingue essentiel-lement decomparaison-lexiques-formes.plpar la deuxième partie (lignes 14 à 25)qui comporte une première sélection des formes parmi lesquelles les néologismessont recherchés. Deux critères sont considérés : l’un sur les catégories et l’autre surles lemmes. Le premier impose l’appartenance de la catégorie de la forme$cat àla liste des catégories ouvertes, implémentée comme une constante de type hachage%ouverte dont les clés sont les catégories visées (ligne 15). L’appartenance peut ainsiêtre vérifiée au moyen de la fonctiondefined(première partie de la condition en ligne21). Le deuxième critère porte sur les lemmes et élimine ceuxqui contiennent descaractères qui ne sont pas des lettres minuscules (deuxièmepartie de la condition enligne 21). Il est mis en œuvre par l’expression régulière/^\pLl+$/ qui utilise lapropriété UnicodeLl des lettres minuscules (voir annexe A2). Les formes des motsdu texte qui satisfont les deux critères sont stockées dans le hachage%text . Ellessont au préalable converties en minuscules par la fonctionlc (ligne 22). L’utilisationdu hachage%text permet d’éviter la répétition des néologismes ayant plusieurs oc-currences dans le texte.

8.9. Déterminer la catégorie d’une forme inconnue (word guessing)

Il arrive souvent que l’on doive connaître les catégories d’une liste de mots in-connus comme par exemple des termes d’un domaine particulier, des formes issues

Page 284: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

292 Perl pour les linguistes

d’un corpus. La catégorisation de ces mots permet par exemple de les utiliser dansdes constructions morphologiques ou syntagmatiques pour réaliser des interrogationsautomatiques.

Le principe de découverte des catégories repose sur l’observation que les marquesflexionnelles et dérivationnelles significatives sur le plan catégoriel se trouvent, enfrançais, à la fin des mots. En d’autres termes, un mot inconnudont la finale est iden-tique à celle d’un mot connu qui appartient à une catégoriec a de bonnes chancesd’être lui aussi de catégoriec. Par exemple, le motkératolytiqueest absent deMor-phalou; néanmoins on peut prédire à partir de ce dictionnaire que c’est un adjectifcar il se termine commebactériolytique, hémolytique, pneumatolytique,protéolytique,etc., qui sont tous des adjectifs. La catégorie proposée pour une forme inconnue par laméthode décrite n’est pas exempte d’erreurs. Certaines proximités graphémiques pou-vant être à l’origine de prédictions fausses. La découvertedes catégories est en faitd’autant plus sûre que la finale partagée par le mot inconnu avec les mots qui serventde modèle est longue et que le nombre de ces modèles est élevé.

La prédiction des catégories des formes inconnues pouvant être rattachées à plu-sieurs catégories constitue un autre problème à résoudre. Deux stratégies sont envi-sageables. La première consiste à associer à la forme toutesles catégories possibles.C’est la solution qui convient pour un mot commenégativistequi est à la fois un nomet un adjectif comme le sontnativiste, normativiste, etc. La deuxième sélectionne uneseule catégorie et convient mieux à un mot commegondolementqui est uniquementnominal, malgré le fait qu’il partage la même finale que les adverbesfrivolementetbénévolement.

En pratique, la prédiction des catégories se fait en compilant une table de finalesgraphémiques qui fournit pour chacune de ses entrées la liste des catégories observées.On compare ensuite les finales du mot inconnu aux entrées de latable, en retenant lafinale la plus longue.

Deux versions d’un programme de détermination de la catégorie d’un mot inconnusont proposées dans la suite de cette section :

– la première (determination-categorie.pl) propose comme catégorie celle qui estla plus fréquente pour la finale retenue ;

– la seconde (determination-categories-multi.pl) propose plusieurs catégorieslorsque les prédictions sont considérées comme sûres ou pour améliorer la cohérencedes résultats.

Ces deux programmes utilisent un lexique de référence pour rapprocher les formesinconnues de mots déjà catégorisés.

Page 285: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Traitements lexicaux 293

8.9.1. Version simple

Listing 8.10 – determination-categorie.plPrédiction déterministe de la catégorie d’une liste de motsinconnus

1 use strict;2 use locale;3 if ($#ARGV != 0)4 die "Usage : ", $0, " LEXIQUE_REFERENCE\n";5 6 open(LEX, "<", $ARGV[0]) or die "impossible d’ouvrir ", $AR GV[0];7 my %finale;8 while (my $ligne = <LEX>)9 chomp($ligne);

10 my ($forme, $lemme, $cat) = split(/\t/, $ligne);11 my $l = length($forme);12 for (my $i = 0; $i < $l; $i++)13 $finalesubstr($forme, $i)$cat ++;14 15 16 close(LEX);17 while (my $ligne = <STDIN>)18 chomp($ligne);19 my $l = length($ligne);20 for (my $i = 0; $i < $l; $i++)21 my $f = substr($ligne, $i);22 if (defined($finale$f))23 my @c = sort $finale$f$b <=> $finale$f$a;

keys %$finale$f;24 print $ligne, "\t", $c[0], "\n";25 last;26 27 28

Ligne de commande :perl determination-categorie.pl lexique_de_référence <

liste_de_mots_inconnus

Exemple :perl determination-categorie.pl C:\PPL\Lexiques\morph alou.txt <

formes-lefff.txt

où formes-lefff.txt contient une liste de formes de Lefff absentes deMorpha-lou ; chacune apparaît sur une ligne séparée ; elles peuvent êtrerepérées au moyen duprogrammecomparaison-lexiques-formes.pl.

Entrée (extrait) :

salicacéesalicinée

Page 286: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

294 Perl pour les linguistes

salicinéessalicionalsalicionalssaliculturesaliculturessalinisasalinisaisalinisaient

Résultat (extrait) :

salicacée Afpfssalicinée Vmps-sfsalicinées Ncfpsalicional Afpmssalicionals Ncmpsaliculture Ncfssalicultures Ncfpsalinisa Vmis3s-salinisai Vmis1s-salinisaient Vmii3p-

Détails du programme :

La version simple du programme comporte deux parties :

1) la lecture du lexique et la compilation de la table des finales ;

2) la recherche de la finale la plus longue de chaque forme inconnue et sélectionde la catégorie la plus fréquemment observée pour cette finale.

Dans la première partie du programme (lignes 6 à 16), les entrées du lexique sontlues. Seules la forme et la catégorie sont utilisées. Le programme calcule tous lessuffixes possibles de la forme en utilisant la fonctionsubstr et en faisant varier laposition de début$i . Il enregistre ces finales munies de la catégorie$cat dans lehachage%finale et incrémente de 1 le nombre des occurrences observées en utilisantl’opérateur++ (ligne 13).

Dans la deuxième partie du programme (lignes 17 à 28), les mots à catégoriser sontlus sur l’entrée standard. Leurs finales sont considérées tour à tour, de la plus longue àla plus courte. Dès qu’une finale est répertoriée dans la table%finale , la catégorie quilui est la plus fréquemment associée est identifiée (ligne 23) : 1) la liste des catégoriesqui lui sont associées est extraite en utilisant la fonctionkeys; 2) la liste est triéepar ordre de fréquence décroissante en fournissant àsort un critère de comparaisonspécifique ; 3) la catégorie la plus fréquente est alors le premier élément de la listetriée. La forme et la catégorie obtenue sont alors affichées (ligne 24). L’instructionlast (ligne 25) est ensuite exécutée pour sortir de la bouclefor et ne pas considérer lesfinales suivantes. Cette commande permet d’arrêter l’exécution de la boucle la plus

Page 287: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Traitements lexicaux 295

interne (while, for , foreach, etc.) dans laquelle elle se trouve et évite ici d’avoir àgérer une variable spécifique supplémentaire pour contrôler l’itération de la boucle.

8.9.2. Version élaborée

Plusieurs améliorations peuvent être apportées à ce programme. La premièreconsiste à ne prendre en compte que les finales dont la taille dépasse un nombreminimal de caractères, que l’on peut par exemple fixer à 3. La prédiction des ca-tégories ne peut alors plus se faire sur la base d’un seul caractère. Cette contrainteempêche le programme de proposer des réponses non fondées etarbitraires ; cer-tains mots ne sont donc pas catégorisés. La catégorisation mise en œuvre dans leprogrammedetermination-categorie.plsouffre aussi d’un problème de cohérence desrésultats. Par exemple, un adjectif commeapprouvablesest uniquement catégorisécomme étant au masculin pluriel alors que c’est aussi une forme au féminin pluriel.De même,bidouillais est catégorisé comme un verbe à l’indicatif imparfait 2e per-sonne du singulier alors que c’est aussi une forme verbale à l’indicatif imparfait 1re

personne du singulier. Un troisième cas similaire est celuid’une forme commepro-ductivistequi est à la fois un nom et un adjectif, féminin et masculin. Leprogrammesuivant implémente l’ensemble de ces améliorations.

Listing 8.11– determination-categories-multi.plPrédiction non déterministe de la catégorie d’une liste de mots inconnus

1 use strict;2 use locale;3

4 if ($#ARGV != 0)5 die "Usage : ", $0, " LEXIQUE_REFERENCE\n";6 7 open(LEX, "<", $ARGV[0]) or die "impossible d’ouvrir ", $AR GV[0];8 my %finale;9 while (my $ligne = <LEX>)

10 chomp($ligne);11 my ($forme, $lemme, $cat) = split(/\t/, $ligne);12 my $l = length($forme);13 for (my $i = 0; $i < $l - 3; $i++)14 $finalesubstr($forme, $i)$cat ++;15 16 17 close(LEX);18 while (my $ligne = <STDIN>)19 chomp($ligne);20 my $l = length($ligne);21 for(my $i = 0; $i < $l - 3; $i++)22 my $f = substr($ligne, $i);23 if (defined($finale$f))24 if ($l - $i > 7)25 foreach my $c (keys %$finale$f)26 print join("\t", $ligne, $c), "\n";27

Page 288: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

296 Perl pour les linguistes

28 29 else30 my @c = sort $finale$f$b <=>

$finale$f$a; keys %$finale$f;31 if ($c[0] =~ /^(A|V)/)32 my $t = $1;33 foreach my $c (grep(/^$t/,

keys %$finale$f))34 print $ligne, "\t", $c, "\n";35 36 37 else38 print $ligne, "\t", $c[0], "\n";39 40 41 last;42 43 44

Ligne de commande :perl determination-categories-multi.pl lexique_de_référence <

liste_de_mots_inconnus

Exemple :perl determination-categories-multi.pl

C:\PPL\Lexiques\morphalou.txt < formes-lefff.txt

Entrée (extrait) :

productivisteproductivistesprofessionnaliseprofessionnalisentprofessionnaliser

Résultat (extrait) :

productiviste Ncmsproductiviste Afpfsproductiviste Ncfsproductiviste Afpmsproductivistes Afpmpproductivistes Ncmpproductivistes Ncfpproductivistes Afpfpprofessionnalise Vmsp1s-professionnalise Vmip1s-professionnalise Vmsp3s-professionnalise Vmip3s-professionnalise Vmmp2s-professionnalisent Vmsp3p-

Page 289: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Traitements lexicaux 297

professionnalisent Vmip3p-professionnaliser Vmn----

Détails du programme :

La première partie du programme (lignes 7 à 17) est pratiquement identique à cellededetermination-categorie.pl. Le critère de longueur minimale des finales est mis enplace au niveau de la condition de contrôle dans la bouclefor (ligne 13). Notons quecette contrainte intervient également lors du calcul des finales des mots à catégoriser(ligne 21).

La deuxième partie du programme implémente les autres améliorations, à savoirque toutes les catégories possibles sont proposées lorsqueles finales sont suffisammentlongues (8 caractères ou plus ; lignes 24 à 27). Pour les autres finales, le programmesélectionne la catégorie la plus fréquente de la même manière que dansdetermination-categorie.pl. Cependant, si cette catégorie est un verbe ou un adjectif, l’ensemble desétiquettes verbales (resp. adjectivales) associées à la finale sont aussi retenues. Cesont en effet, pour le français, les deux catégories ouvertes dont les mots disposentnormalement de flexion complète. L’extension de la liste desétiquettes n’est pas réa-lisée pour les autres catégories, notamment pour les noms. Les finales ne constituentpas en effet une information suffisamment discriminante pour décider si un nom estinvariable ou pas.

Plus précisément, le programme vérifie que$c[0] commence parA ouV au moyende une expression régulière, mémorise ce premier caractèredans la variable spéciale$1 (ligne 31) puis le recopie dans une variable normale$t (ligne 32). Il sélectionneensuite l’ensemble des étiquettes qui commencent par$t en utilisant la fonctiongrepqui permet d’appliquer une expression régulière aux élément d’une liste, en l’occur-rence/^$t/ aux clés du hachage%$finale$f où$f est la finale retenue (ligne33). Le résultat de ce filtrage est l’ensemble des éléments deliste initiale pour lesquelsl’expression régulière s’applique.

8.10. Fléchir des lemmes inconnus

Le programmeinstances-construction.plpermet de générer les instances d’uneconstruction en s’appuyant sur les formes fléchies décritesdans un lexique de ré-férence. Mais dans le cas où le lemme est absent du lexique, aucun résultat n’estproduit. Le traitement lexical suivant permet de résoudre cette difficulté en générantl’ensemble des formes fléchies pour une liste de mots absentsd’un lexique de réfé-rence. Plus précisément, les mots inconnus sont rapprochésdes lemmes du lexique deréférence puis fléchis comme le sont ces derniers. La flexion des mots inconnus peutêtre réalisée soit uniquement à partir de leur forme graphémique, soit en indiquant lacatégorie de ces mots. Dans le cas où aucune catégorie n’est fournie, cette dernière

Page 290: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

298 Perl pour les linguistes

doit être préalablement prédite afin de garantir la cohérence de l’ensemble des formesgénérées. Ce traitement étant une simple découverte de la catégorie de mots incon-nus, nous renvoyons le lecteur à la section 8.9. Seule la flexion des lemmes pour unecatégorie donnée est donc traitée dans le programme suivant. Elle doit être indiquéepour chaque lemme en l’ajoutant à la fin de ce dernier, précédée d’une barre oblique.Par exemple, pour fléchir le verbefeuilletonner, le système doit recevoir en entrée lachaînefeuilletonner/V .

La méthode utilisée repose sur deux hypothèses : 1) les lemmes et les formessont décomposables graphémiquement en un radical et une marque de flexion ; 2)une forme et son lemme ont le même radical. Par exemple, les éléments d’un coupleforme / lemme commeappellerons/ appelerpeuvent être décomposés en :

appel · lerons / appel · er

appe · llerons / appe · ler

app · ellerons / app · eler

ap · pellerons / ap · peler

a · ppellerons / ap · ppeler

ǫ · appellerons / ǫ · appeler

où ǫ représente la chaîne vide. Ces décompositions purement mécaniques ne sont na-turellement pas linguistiquement motivées. Le programme compile dans une table lescouples de finales correspondant à toutes les décompositions possibles de toutes lesentrées du lexique de référence (lerons / er ; llerons / ler ; ellerons / eler ;pellerons / peler ... pourappellerons/ appeler). Il associe de plus à chaque couplel’étiquette de la forme dont il est issu (Vmif1p- pour cet exemple). Plusieurs sché-mas (c’est-à-dire couples de finales flexionnelles) sont donc mémorisés pour chaquecouple forme / lemme ; la plupart comportent une redondance importante, une partiedu radical commun à la forme et au lemme étant conservée dans les finales flexion-nelles. Cette redondance permet de coller au plus près des entrées individuelles dulexique de référence.

Pour illustrer cette méthode, considérons le calcul de la forme fléchie à la 2e per-sonne du singulier du présent de l’indicatif d’un verbe comme feuilletonner. Le pro-gramme commence par déterminer la finale la plus longue defeuilletonnerpour la-quelle il existe un schéma flexionnel ayant comme étiquetteVmip2s- . Dans la tabledes schémas construite à partir deMorphalou, cette finale estilletonner . Elle ap-paraît pour l’étiquetteVmip2s- dans le schémailletonner / illetonnes qui pro-vient du verbeœilletonneret de sa forme fléchie à la 2e personne du singulier duprésent de l’indicatifœilletonnes. La forme fléchie du verbe lemmefeuilletonnerestobtenue en décomposant ce dernier enfeu · illetonner . On peut ainsi créer la dé-composition de la forme fléchie correspondantefeu · illetonnes , puis la formefeuilletonnesen concaténant les deux parties.

Page 291: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Traitements lexicaux 299

Le programme suivant réalise les deux opérations qui viennent d’être décrites. Ilcompile un ensemble de schémas flexionnels à partir d’un lexique de référence, puisgénère l’ensemble des formes fléchies d’une liste de lemmes munis de leurs catégo-ries. La catégorie figure à la fin de chaque lemme, précédée d’une barre oblique (parexemplefeuilletonner/V ).

Listing 8.12 – flexion-inconnu.plFlexion d’un lemme inconnu

1 use strict;2 use locale;3 if ($#ARGV != 0)4 die "Usage : ", $0, " LEXIQUE_REFERENCE\n";5 6 open(LEX, "<", $ARGV[0]) or die "impossible d’ouvrir ", $AR GV[0];7 my %cats;8 my %flex;9 while (my $ligne = <LEX>)

10 chomp($ligne);11 my ($forme, $lemme, $cat) = split(/\t/, $ligne);12 my $c = substr($cat, 0, 1);13 $cats$c$cat = 1;14 my $ll = length($lemme);15 my $lf = length($forme);16 my $l;17 if ($ll < $lf)18 $l = $ll;19 20 else21 $l = $lf;22 23 for (my $i = 0; $i <= $l; $i++)24 if (substr($lemme, 0, $i) eq substr($forme, 0, $i))25 $flex$csubstr($lemme, $i)$cat

substr($forme, $i) ++;26 27 28 29 while (my $ligne = <STDIN>)30 chomp($ligne);31 my ($lemme, $c);32 if ($ligne =~ /^(. * )\/(\pLu)$/)33 $lemme = $1;34 $c = $2;35 my $l = length($lemme);36 for (my $i = 0; $i <= $l; $i++)37 my $finale = substr($lemme, $i);38 if (defined($flex$c$finale))39 foreach my $cat (keys %$cats$c)40 if (defined($flex$c$finale$cat))41 my @flexion = sort

$flex$c$finale$cat$b <=>$flex$c$finale$cat$a;keys %$flex$c$finale$cat;

42 print substr($lemme, 0, $i), $flexion[0],"\t", $lemme, "\t", $cat, "\n";

43

Page 292: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

300 Perl pour les linguistes

44 45 last;46 47 48 49 else50 warn $ligne, " format incorrect";51 52

Ligne de commande :perl flexion-inconnu.pl lexique_de_référence < liste_de_lemmes

Exemple :perl flexion-inconnu.pl C:\PPL\Lexiques\morphalou.txt <

liste-lemmes.txt

Entrée (extrait) :

feuilletonner/Vguéable/Améprisabilité/Nmunicipalement/R

Résultat (extrait) :

feuilletonnez feuilletonner Vmip2p-feuilletonnerions feuilletonner Vmcp1p-feuilletonnent feuilletonner Vmip3p-feuilletonnée feuilletonner Vmps-sffeuilletonnerais feuilletonner Vmcp1s-feuilletonne feuilletonner Vmsp1s-feuilletonnes feuilletonner Vmsp2s-feuilletonneraient feuilletonner Vmcp3p-feuilletonne feuilletonner Vmip3s-feuilletonnons feuilletonner Vmip1p-

Détails du programme :

Compilation de la table des schémas.Dans la première partie (lignes 6 à 28), lelexique est lu. Pour chaque entrée, le programme mémorise dans le hachage%cats

le fait que l’étiquette$cat est compatible avec la catégorie$c (lignes 13) où$c

contient le premier caractère de$cat (lignes 12). Les schémas flexionnels qui peuventdécrire l’entrée sont ensuite analysés et stockés dans le hachage%flex . Les clés dece hachage à 4 niveaux sont :

1) la catégorie ;

2) la finale du lemme ;

Page 293: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Traitements lexicaux 301

3) l’étiquette morphosyntaxique complète ;

4) la finale de la forme fléchie.

Par exemple, les quatre premiers enregistrements engendrés par la formeappelle-ronset son lemmeappelersont :

V appeler Vmip2s- appellerons

V ppeler Vmip2s- ppellerons

V peler Vmip2s- pellerons

V eler Vmip2s- ellerons

L’ordre de ces clés est déterminé par celui dans lequel ces informations sont utili-sées dans la deuxième partie du programme. Pour calculer lesfinales, le programmedétermine d’abord au moyen de la fonctionlength la longueur du lemme$ll et cellede la forme fléchie$lf (lignes 14 et 15). La plus courte de ces longueurs$l est lalongueur maximale possible du radical commun au lemme et à laforme (lignes 17à 22). Le programme extrait alors du lemme et de sa forme deux préfixes de mêmetaille en utilisant à nouveau la fonctionsubstr (la position de début est égale à 0) etles compare au moyen de l’opérateureq d’égalité entre chaînes de caractères (ligne24). S’il s’agit d’un radical commun, les finales correspondantes (extraites parsubstravec une position de début est égal à$i ), complétées par la catégorie et l’étiquettemorphosyntaxique sont ajoutées au hachage%flex . La valeur associée à cette entréeest le nombre de couples observés pouvant être décrits par ceschéma. Elle est doncincrémentée de 1via l’opérateur++ chaque fois qu’il est rencontré (ligne 25). Lenombre de ces occurrences permet de savoir si une flexion est régulière (c’est-à-diresuffisamment fréquente) ou exceptionnelle (c’est-à-dire rare).

Lecture et analyse des lemmes à fléchir.Dans sa deuxième partie le programmecalcule les formes fléchies des lemmes lus sur l’entrée standard. Ces lemmes doiventêtre munis de leurs catégories. La ligne est analysée au moyen d’une expression régu-lière pour séparer le lemme de sa catégorie (ligne 32). Dans l’expression régulière, lescaractères qui précèdent la barre oblique d’une part et la catégorie de l’autre sont en-tourés de parenthèses afin d’être mémorisés puis conservés dans les variables$lemme

et$c . Si la ligne n’a pas le bon format, un message est affiché au moyen de la fonctionwarn et l’entrée est ignorée (lignes 49 à 51).

Sélection de la meilleure finale et génération des formes.Pour les lignes dont leformat est correct, le programme considère tour à tour les finales du lemme par ordrede longueur décroissante, c’est-à-dire en commençant par le lemme entier (lignes 35 à47). Dès qu’une des finales ($finale ) est répertoriée dans la table%flex pour la ca-tégorie$c (l’existence de l’entrée dans la table est déterminé par la fonctiondefined;ligne 38), les formes correspondant à l’ensemble des étiquettes morphosyntaxiques dela catégorie$c et qui sont définies pour$finale sont générées (lignes 39 à 46).

Page 294: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

302 Perl pour les linguistes

Les étiquettes de la catégorie$c sont les clés dans le hachage%$cats$c .Parmi ces dernières, seules celles qui ont été rencontrées pour la finale$finale sontconsidérées (ligne 40). Le programme sélectionne ensuite pour l’étiquette$cat lafinale flexionnelle celle qui est la plus fréquemment associée à$finale . Plusieursfinales flexionnelles peuvent en effet être associées à la même finale de lemme pourune étiquette donnée commeer qui pour le présent de l’indicatif, 3e personne dusingulier (Vmip3s- ) peut être associée àe (nager / nage), à te (jeter / jette) ou àle

(appeler / appelle). La finale flexionnelle par défaut est la plus fréquente des trois,en l’occurrencee. Les autres finales sont utilisées dans des contextes particuliers,notamment pour les lemmes en-eter et -eler). La flexion ainsi retenue permet degénérer la forme fléchie en la concaténant au radical du lemme(ligne 49). Ce lemmeétant traité, le programme passe alors à l’entrée suivante sans poursuivre la recherched’une autre finale (commandelast en ligne 45).

Lemmatisation :

La technique qui vient d’être présentée peut facilement être adaptée pour réaliserun lemmatiseur pour un texte étiqueté, s’il n’est pas lemmatisé ou si la lemmatisationproposée n’est pas satisfaisante. Il suffit simplement d’utiliser les schémas flexionnelsen sens inverse. Cette tâche pose une difficulté supplémentaire : traduire au préalablele jeu d’étiquettes du lexique de référence dans celui du catégoriseur.

8.11. Morphologie dérivationnelle

Le programmeinstances-construction.pl, décrit en section 8.7, permet de créerles instances de constructions syntagmatiques. Mais le lexique peut aussi être utilisépour créer des instances de constructions morphologiques,commein-V -able, N -iqueou A-iser où V , N et A représentent respectivement un radical de verbe, de nom etd’adjectif.

Deux techniques peuvent être utilisées :

1) la concaténation d’un affixe ou la substitution de ce dernier à quelques finalesprédéterminées ;

2) l’utilisation de schémas dérivationnels permettant de respecter plus fidèlementles allomorphies (variations de la forme sonore) et les allographies (variations de laforme graphémique) spécifiques à chaque affixe.

Ces deux approches sont présentées successivement dans lesdeux sous-sections sui-vantes.

Page 295: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Traitements lexicaux 303

8.11.1. Concaténation et substitution

La première technique est similaire à celle qui est mise en œuvre dansinstances-construction.pl. Il s’agit par exemple de substituer un suffixe comme-ableà certainesdes finales de l’infinitif comme-er : acclimater→ acclimatable.

Cette méthode présente l’avantage d’être simple et facile àmettre en œuvre ; lesprogrammes se réduisent à quelques substitutions au moyen d’expressions régulières.Elle donne de bons résultats pour les affixations les plus régulières comme la préfixa-tion et certaines suffixations (-able, -age). En revanche, elle implique une analyse lin-guistique préalable de la construction car il faut connaître les mots de base sur lesquelssont formés les dérivés ; elle nécessite un programme différent pour chaque construc-tion ; elle ne peut pas toujours être mise en œuvre ; ses résultats peuvent très mauvaispour des suffixes comme-ité (captif → captivité, casuel→ casualité, caustique→causticité, etc.).

8.11.1.1.Préfixation

Cette technique donne de bons résultats pour la préfixation car cette dernière serésume le plus souvent à la simple concaténation du préfixe etqu’elle implique engénéral peu de variations allomorphiques. Elle peut être illustrée par le programmesuivant qui crée des formes préfixées parin-. Ce préfixe apparaît sous 4 formes :

– im- devant les mots qui commencent parb (imbattable), m (immatériel) et p

(improbable) ;

– ir- devant les mots qui commencent parr (irréaliste) ;

– il- devant les mots qui commencent parl (illettré) ;

– in- dans tous les autres cas (incalculable).

Deux situations échappent cependant à cette description sommaire et au programmeprefixation-in.plqui l’implémente. Elle ne prévoit rien pour les adjectifs commerougequi ne peuvent pas servir de base la préfixation parin- (* inrouge). De même, cer-taines bases qui commencent parr ou l acceptent aussi la forme canonique du suf-fixe in- commeinlisible ou inrespirablequi coexistent avecillisible et irrespirable.Pour d’autres bases, commelouable, seul le dérivé enin- est attesté (inlouablemais* illouable). Il n’est donc pas envisageable de réaliser un programme capable deconstruire tous les mots préfixés en-in, et ceux-là seulement ;prefixation-in.plconsti-tue un compromis légèrement restrictif qui produit des formes relativement « nor-mées ». Toutefois, selon l’utilisation envisagée, ces résultats peuvent ou doivent êtrerévisés manuellement pour en éliminer les éventuelles erreurs.

Page 296: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

304 Perl pour les linguistes

Listing 8.13 – prefixation-in.plPréfixation enin- des formes lues sur l’entrée standard

1 use strict;2 use locale;3 while (my $ligne = <STDIN>)4 chomp($ligne);5 if($ligne =~ /^[bmp]/)6 print "im", $ligne, "\n";7 8 elsif($ligne =~ /^([lr])/)9 print "i", $1, $ligne, "\n";

10 11 else12 print "in", $ligne, "\n";13 14

Ligne de commande :perl prefixation-in.pl < liste_d’adjectifs

Exemple :perl prefixation-in.pl < liste-adjectifs.txt

Entrée :

buvableévoluélimitématurenettoyableprudentrégulier

Résultat :

imbuvableinévoluéillimitéimmatureinnettoyableimprudentirrégulier

Détails du programme :

Le programmeprefixation-in.plcalcule les mots préfixés enin- en distinguant 3cas. Les mots qui commencent enb, met p sont affichés précédés deim (lignes 5 et6) ; ceux qui commencent parl et r sont préfixés en doublant leur premier caractère,

Page 297: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Traitements lexicaux 305

mémorisé dans$1 (la disjonction[lr] est entourée de parenthèses dans l’expressionrégulière en ligne 8) ; tous les autres mots reçoivent le préfixe in (ligne 12).

Ce programme réalise correctement la tâche prévue, même si une bonne partie desadjectifs préfixés enin- ne sont pas formés sur des bases adjectivales attestés, maisdirectement à partir d’un verbe ou d’un nomvia des constructions commein-V -ableou in-N -able (intitrable est par exemple créé directement à partir detitre et non detitrable).

8.11.1.2.Suffixation

Le traitement de la suffixation est plus difficile car elle entraîne fréquemment desvariations allomorphiques et a recours à des radicaux différents de ceux des lemmes.La substitution simple de la finale de la base par le suffixe estnéanmoins utilisablepour des suffixations comme-ableou-ageà condition, dans les deux cas, que la formede base soit le participe présent (brunissant→ brunissage, confisant→ confisage)et non de l’infinitif (brunir, confire). Plus précisément,-agecomme-able utilise lethème du participe présent, analysé comme unthème de supinpar [PLE 88] et quicorrespond authème 4dans la terminologie de [BON 03].

La technique la plus simple consiste donc à fléchir les lemmesque l’on souhaitedériver au moyen du programmeflexion-inconnu.pl(listing 8.12), puis extraire lesparticipes présents en se basant sur leur étiquette (Vmpp--- ) et fournir ces formescomme entrée au programme suivant qui réalise une simple substitution de la finale-ant par -age. La principale difficulté pour réaliser cette suffixation n’est donc pasinformatique mais linguistique : la qualité du résultat dépend totalement de l’identifi-cation des bonnes formes de base, en l’occurrence du fait queles déverbaux en-agesont construits sur le radical du participe présent.

Listing 8.14 – suffixation-age.plSuffixation en-ageà partir de formes au participe présent

1 use strict;2 use locale;3 while (my $ligne = <STDIN>)4 chomp($ligne);5 if($ligne =~ /^(. * )ant$/)6 print $1, "age\n";7 8 else9 warn $ligne, " la forme n’est pas un participe présent\n";

10 11

Ligne de commande :perl suffixation-age.pl < liste_de_participes_présents

Page 298: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

306 Perl pour les linguistes

Exemple :perl suffixation-age.pl < liste-participes-presents.tx t

Résultat :

confondagedépassagefronçageplaignage

Détails du programme :

Ce programme vérifie d’une part que l’entrée se termine en-ant, la marque duparticipe présent. Si c’est le cas, il affiche le radical, c’est-à-dire la partie du la formed’entrée qui précèdeant , suivi du suffixeage (ligne 6). Le radical est mémorisé dans$1 (ligne 5). Dans le cas où la forme fournie ne se termine pas par-ant, un messaged’erreur est affiché au moyen de la fonctionwarn (ligne 9).

8.11.2. Apprendre et appliquer des schémas dérivationnels

Il existe une autre méthode pour créer des mots dérivés qui présente sur la précé-dente plusieurs avantages dont le principal est de ne pas nécessiter une analyse ou uneconnaissance de la construction utilisée. Elle se compose de deux programmes per-mettant de traiter toutes les affixations : le premier compile un ensemble de schémasd’affixation et le second les applique à un ensemble de mots pour créer leurs dérivés.La méthode n’est détaillée dans cette section que pour la suffixation ; l’adaptation deces programmes à la préfixation ne présente pas de difficulté particulière.

Les schémas de suffixation sur lesquels repose cette méthodesont similaires auxschémas flexionnels décrits en section 8.10. Deux différences existent entre la flexiondes lemmes inconnus et la dérivation morphologique : pour laseconde, 1) seules sontconsidérées les relations entre lemmes ; 2) le lexique de référence ne fournit pas lesrelations dérivationnelles qui s’établissent entre ces entrées. Il ne contient pas parexemple d’information explicite sur le fait quegénérationest dérivé degénérerparsuffixation en-ion6. La principale difficulté de la phase d’acquisition des schémasdérivationnels est d’identifier les couples de lemmes qui sont effectivement en relationmorphologique.

Les schémas de suffixation reposent sur l’hypothèse que les mots sont constituésd’un radical et d’un suffixe et que les mots qui partagent le même radical ont de bonnes

6. Dans le cas particulier des noms d’action déverbaux, cetteinformation est disponible dansun lexique commeVerbaction.

Page 299: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Traitements lexicaux 307

chances d’être morphologiquementapparentés. C’est le caspar exemple degénérationet générablequ’il est possible de décomposer engénér · ation et génér · able etqui sont tous les deux dérivés du même verbegénérer. Ce couple permet d’identifierun schéma de suffixationation / able qui peut être utilisé pour créer des dérivés en-ableà partir de dérivés en-ion (commemodulableà partir demodulation).

8.11.2.1.Apprentissage de schémas de suffixation

L’apprentissage des schémas est une opération purement mécanique qui calculetous les couples de suffixes possibles pour tous les couples de lemmes d’un lexique deréférence. Cette opération est donc relativement gourmande en mémoire et en tempsde calcul. Mais cet apprentissage n’est à réaliser qu’une seule fois : une fois acquis, lesschémas peuvent être utilisés pour toutes les suffixations suffisamment représentéesdans le lexique de référence. L’apprentissage peut cependant être allégé en sélection-nant un ensemble de mots dérivés du lexique de référence et unensemble de mots debase. Par exemple, pour acquérir des schémas suffixation en-ion, on peut limiter l’en-semble des couples destinés à l’apprentissage à ceux dont lepremier membre est unverbe et le second un nom qui se termine en-ion. Les schémas ainsi constitués ne sontalors utilisables que pour la construction de noms en-ion à partir de bases verbales.

La principale difficulté de l’apprentissage des schémas estde séparer les schémasqui décrivent des relations morphologiques réelles commegénération↔ générablede ceux qui correspondent à des accidentsglouton 6↔ glousserou nier 6↔ noyer. Lasélection s’appuie sur trois constations :

1) les schémas ayant un nombre suffisant d’occurrences correspondent à des re-lations morphologiques correctes. C’est par exemple le casdu schémaer / able quidécrit 435 couples de lemmes (démonter / démontable) du lexiqueMorphalou;

2) les couples de lexèmes qui partagent un radical suffisamment long sont nor-malement morphologiquement apparentés. C’est le cas deaccrémentitiel / accrémen-tition, malgré le fait que le couple de finalesel / on soit rare. A l’inverse, les initialestrès courtes ne sont en général pas des radicaux. Le partage de ces initiales est gé-néralement accidentel comme dansnier / noyer, et cela même si le couple de finaleier / oyer décrit aussi des relations morphologiques effectives comme charrier /charroyer, déplier / déployeroudévier / dévoyer;

3) les finales très longues correspondent généralement à desradicaux préfixéscommetechnique / métrique que l’on rencontre avec les mêmes préfixes :psycho-,pyro-ou radio-.

Ces trois paramètres – nombre d’occurrences, taille du radical et taille du suffixe –permettent de contrôler l’apprentissage des schémas en fonction des besoins. Ces der-niers ne sont pas les mêmes selon que les schémas sont utilisés pour analyser leslemmes d’un lexique ou pour créer des mots nouveaux. Dans le second cas, il est pré-férable de privilégier la fréquence, gage de régularité de la relation morphologique.

Page 300: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

308 Perl pour les linguistes

Les valeurs habituellement utilisées pour les 3 paramètressont : 5 pour le nombre mi-nimal d’occurrences du schéma ; 3 pour la taille minimale du radical ; 8 pour la taillemaximale du suffixe. Ce sont les valeurs par défaut pour les 3 options-l , -m et -M

du programme suivant qui permet d’acquérir des schémas de suffixation à partir d’unlexique flexionnel commeMorphalou.

Listing 8.15 – apprentissage-suffixation.plApprentissage de schémas de suffixation

1 use strict;2 use locale;3 use Getopt::Std;4 our ($opt_l, $opt_m, $opt_M);5 $opt_l = 5;6 $opt_m = 3;7 $opt_M = 8;8 getopts("l:m:M:");9 if ($#ARGV != 1)

10 die "Usage : ", $0, " [-m TAILLE_MINIMALE_RADICAL][-M TAILLE_MAXIMALE_SUFFIXE][-l NOMBRE_MINIMAL_OCCURRENCES]LEXIQUE_BASES LEXIQUE_DERIVES\n";

11 12 my %bases = %analyser_lexique($ARGV[0]);13 my %derives = %analyser_lexique($ARGV[1]);14 my %schemas;15 foreach my $radical (keys %derives)16 if (defined($bases$radical))17 foreach my $suff1 (keys %$bases$radical)18 foreach my $suff2 (keys %$derives$radical)19 $schemas$suff1$suff2 ++;20 21 22 23 24 foreach my $suff1 (keys %schemas)25 foreach my $suff2 (keys %$schemas$suff1)26 if (($schemas$suff1$suff2 >= $opt_l) and

($suff1 ne $suff2))27 print $suff1, "\t", $suff2, "\t",

$schemas$suff1$suff2, "\n" ;28 29 30 31 sub analyser_lexique32 my ($fichier) = @_;33 my %lex;34 open(LEX, "<", $fichier) or die "impossible d’ouvrir ",

$fichier;35 while (my $ligne = <LEX>)36 chomp($ligne);37 my ($forme, $lemme, $cat) = split(/\t/, $ligne);38 my $c = substr($cat, 0, 1);39 my $l = length($lemme);40 my $mg = $l - $opt_M;41 my $m;42 if ($mg < $opt_m)

Page 301: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Traitements lexicaux 309

43 $m = $opt_m;44 45 else46 $m = $mg;47 48 for(my $i = $m; $i <= $l; $i++)49 $lexsubstr($lemme, 0, $i)

substr($lemme, $i) . "/" . $c = 1 ;50 51 52 close(LEX);53 return(\%lex);54

Ligne de commande :perl apprentissage-suffixation.pl -l fréquence_minimale

-m radical_minimal -M suffixe_maximal lexique_bases

lexique_dérivés

Exemple :perl apprentissage-suffixation.pl C:\PPL\Lexiques\mor phalou.txt

C:\PPL\Lexiques\morphalou.txt

Résultat (extrait) :

able/A ir/V 13able/A é/A 268able/A cateur/N 10able/A ationnel/A 5able/A /N 72able/A oir/V 8able/A ure/N 26able/A alisme/N 6able/A ateur/A 70able/A ail/N 5able/A ien/N 5able/A amment/R 5able/A er/V 435

Détails du programme :

Le programme comporte 5 parties : le traitement des options ;l’analyse du lexiquedes mots de base ; l’analyse des dérivés ; la constitution desschémas et le calcul desfréquences ; la sélection des schémas suffisamment fréquents.

Options et arguments. Le programme dispose de 3 options récupérés en utilisantla fonctiongetoptsdu moduleGetopt::Std (voir chapitre 7). Rappelons que lesvariables$opt_l , $opt_m et $opt_M , positionnées par ce module doivent être dé-clarées par la directiveour et nonmy (ligne 4). Ces variables sont initialisées avec

Page 302: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

310 Perl pour les linguistes

leurs valeurs par défaut (lignes 5 à 7) avant d’être confiées àgetopts. On indique àcette fonction que ces options attendent des arguments en faisant suivre les caractèrescorrespondants par ‘: ’ (ligne 8).

Outre les options, le programme attend deux arguments obligatoires : un lexiquede formes de base et un lexique de dérivés. On peut ainsi invoquer le programmeavec comme lexique de bases les verbes deMorphalouet comme lexique de dérivésles adjectifs en-able. Mais l’apprentissage peut aussi se faire avec le même fichiercomme dans l’exemple ci-dessus. Les deux noms de fichiers sont conservés dans laliste @ARGV. Cependant, l’accès à ces valeurs ne doit se faire qu’après l’analyse desoptions pargetopts. La présence des deux arguments est vérifiée (ligne 9) et s’ils nesont pas fournis ou s’il y en a plus de 2, la fonctiondie affiche un message qui indiquela façon dont le programme doit être appelé puis l’arrête (ligne 10).

Analyse des lexiques. Le lexique des bases et celui des dérivés sont analysés suc-cessivement en appelant la fonctionanalyser_lexique (lignes 12 et 13) qui permetde factoriser le code correspondant aux deux traitements. Les résultats sont conser-vés dans les hachages%bases et %derives respectivement (voir programme 8.5 ensection 8.3).

Les lignes du lexique sont lues et analysées. Seuls le lemme stocké dans$lemme

et la catégorie$c représentée par la première lettre de l’étiquette$cat sont utilisés.La fonctionanalyser_lexique calcule pour chaque lemme, l’ensemble de ses dé-compositions en un radical suivi d’une finale. Elle détermine d’abord la position de lapremière coupure en fonction de la longueur du lemme, donnéepar la fonctionlength(ligne 39), et des paramètres$opt_m et $opt_M (lignes 40 à 47). Par exemple, pourle nomjonglerie(la taille $l vaut 9) et avec les valeurs par défaut des paramètres, lataille minimal du radical impose une coupure après le 3e caractère et la taille maxi-male du suffixe une coupure après le 1er caractère (9− 8 = 1). La première coupurese trouve donc après le 3e caractère (3> 1). Plus généralement, la première coupurea donc lieu entre le$m-ième et le$m+1-ième caractère où$mest le plus grand de :

– $opt_m , la taille minimale du radical ;

– l’indice du$opt_M +1-ième caractère de$lemme en partant de la fin. Cette va-leur est$l −$opt_M où $l est la longueur de$lemme.

Les décompositions sont ensuite calculées au moyen de la fonction substr pourtoutes les positions comprises entre$met la fin du lemme (lignes 48 à 50). De plus, lacatégorie du lemme$c est ajoutée à la fin de chaque finale précédée du séparateur ‘/ ’.Les deux éléments de chaque décomposition sont conservés dans le hachage$lex .Une fois toutes les entrées analysées,analyser_lexique retourne la référence duhachage$lex , à savoir\$lex (voir annexe A4).

Page 303: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Traitements lexicaux 311

Enumération des schémas.Les décompositions stockées dans les hachages%bases

et %derives vérifient les contraintes correspondant aux paramètresmet M. Le pro-gramme énumère ensuite tous les schémas induits par ces décompositions en recher-chant les radicaux communs aux mots de base et aux dérivés et en mémorisant lescouples de finales correspondantes (lignes 15 à 23). Les radicaux communs sont iden-tifier en parcourant les clés de premier niveau de%bases, fournis par la fonctionkeys(ligne 15) et en vérifiant leur présence comme clé du hachage%derives au moyende la fonctiondefined(ligne 16). Les schémas sont conservés sous forme de clés dansle hachage%schemas avec comme valeur le nombre de leurs occurrences. Cette va-leur est donc incrémentée de 1 pour chaque couple de finales rencontré (opérateur++ ;ligne 19).

Sélection des schémas suffisamment fréquents.La dernière étape du programmeparcourt les schémas constitués lors de l’étape précédenteet affiche ceux dont la fré-quence dépasse le seuil$opt_l (lignes 24 à 30). Les schémas dont les deux finalessont identiques sont également éliminés.

Réglage des paramètres :

Le paramètrel est le plus important pour la quantité et la qualité des schémasacquis. Une valeur élevée del (par exemple 10) permet d’obtenir un petit nombre deschémas généraux mais peu redondants. En revanche, avec unevaleur plus faible del(par exemple 3) les schémas sont plus nombreux, plus fins et plus précis.

L’autre paramètre important estm car c’est lui qui contrôle le coût en temps decalcul et en mémoire de l’apprentissage. Une valeur de m inférieure à 3 augmenteconsidérablement le nombre des couples des schémas constitués lors de la 4e étape,sans améliorer réellement la finesse des résultats, ces derniers étant ensuite sélection-nés sur la base de leurs fréquences.

8.11.2.2.Application de schémas de suffixation

Les schémas appris sont utilisés pour générer des mots nouveaux à partir de motsconnus. Cette tâche est normalement réalisée dans le cadre d’une étude particulièrequi ne concerne qu’une classe de constructions morphologiques. On doit donc res-treindre les schémas appris au sous-ensemble permettant decréer ces constructions.Par exemple, si l’on s’intéresse aux noms en-ité, on se limitera aux schémas dontle second membre se termine parité/N . L’extraction du sous-ensemble de sché-mas pertinent pour une suffixation donnée peut être réalisé en utilisant le programmerecherche-expreg-simple.pl(décrit en paragraphe 5.2.3 page 196) avec comme para-mètre l’expression régulière"ité/N\t[0-9]" .

La génération des mots suffixés est une simple substitution d’une des finales dumot base par celle qui lui est associée dans l’un des schémas qui ont été appris. Lesmeilleurs résultats sont obtenus pour les finales du mot baseles plus longues et pour

Page 304: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

312 Perl pour les linguistes

les schémas les plus fréquents. Le programme suivant s’appuie sur ces deux critèrespour créer des dérivés en-ité à partir de mots de base de catégorie quelconque (noms,verbes, adjectifs, adverbes).

Listing 8.16 – suffixation.plSuffixation des mots bases

1 use strict;2 use locale;3 if ($#ARGV != 0)4 die "Usage : ", $0, " SCHÉMAS\n";5 6 open(SCHEM, "<", $ARGV[0]) or die "impossible d’ouvrir ", $ ARGV[0];7 my %schemas;8 while (my $ligne = <SCHEM>)9 chomp($ligne);

10 my ($suff1, $suff2, $freq) = split(/\t/, $ligne);11 $schemas$suff1$suff2 = $freq;12 13 close(SCHEM);14 while (my $ligne = <STDIN>)15 chomp($ligne);16 for (my $i = 0; $i <= length($ligne) - 2; $i++)17 my $suff1 = substr($ligne, $i);18 if (defined($schemas$suff1))19 my @suff = sort $schemas$suff1$b <=>

$schemas$suff1$a;keys %$schemas$suff1;

20 print substr($ligne, 0, $i), $suff[0], "\n";21 last;22 23 24

Ligne de commande :perl suffixation.pl schémas < mots_bases

Exemple :perl suffixation.pl schemas-suffixation-ite.txt < bases -ite.txt

Entrées :

bicaméralisme/Ncapitulairement/Rmonopoliser/Vdiacritique/A

Résultat :

bicaméralité/Ncapitularité/N

Page 305: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Traitements lexicaux 313

monopolité/Ndiacriticité/N

Détails du programme :

Le programme comporte deux parties. Dans la première (lignes 7 à 13), les sché-mas de suffixation sont lus et stockés dans le hachage%schemas. Les finales sontconservés comme clés du hachage et la fréquence comme valeurassociée. Dans ladeuxième partie, les mots à partir desquels les dérivés sontcréés sont lus sur le fluxd’entrée standard. Ces entrées doivent avoir le même formatque les finales des sché-mas de suffixation. Chaque mot doit être suivi de sa catégorie, avec une barre oblique‘ / ’ comme séparateur. Pour chaque entrée, le programme cherche la finale la pluslongue qui fasse partie d’un schéma (voir listing 8.11). Dèsque cette dernière esttrouvée, le programme trie les membres de droite des schémaspar ordre de fréquencedécroissante. La liste des finales de dérivés est obtenue au moyen de la fonctionkeyspuis triée parsort avec une fonction de comparaison numérique des fréquences asso-ciées (ligne 20). La finale de dérivés du schéma le plus fréquent est alors affichée à lasuite du radical du mot de base (ligne 21). La directivelast (ligne 22) permet ensuitede passer directement au mot de base suivant sans exécuter lereste de la bouclefor .

Page 306: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

314

Page 307: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

CHAPITRE 9

Manipulation de données au format XML

9.1. Principes généraux de XML

Les données linguistiques sont, comme on l’a vu au chapitre 1, disponibles sousdifférents formats, que ce soit sous leur forme brute (documents en texte brut ouenrichi) ou à l’issue d’un traitement (textes segmentés, étiquetés, annotés, lexiquesconstruits, etc.). Exploiter de telles données implique donc que l’on adapte les trai-tements aux spécificités de ces formats. De plus, les formatscomplexes (comme leslexiques très riches ou les textes annotés au niveau du discours) nécessitent une struc-ture sophistiquée pour séparer clairement les données des informations associées.

Le métalangage de structuration de données XML permet de dépasser ces diffé-rents problèmes, en appliquant les mêmes principes à tous les types de données. Ilpropose un format facilement manipulable et explicite pouvant s’appliquer à tous lestypes d’information présents dans un document.

Mis en place dans les années 1990, le métalangage XML (eXtended Markup Lan-guage) s’est largement répandu, et l’on trouve désormais des ressources linguistiquesdiffusées sous ce format, ainsi que des programmes de traitement qui produisent leursrésultats en XML. Se basant sur les principes génériques de XML, un ensemble denormes a été élaboré par la communauté des linguistes et des utilisateurs de ressourcestextuelles, afin d’harmoniser la description des données etleurs annotations. C’estnotamment le cas de laText Encoding Initiative(ou TEI1) et duCorpus EncodingStandardou (CES2).

1. http://www.tei-c.org .2. http://www.cs.vassar.edu/CES/ .

315

Page 308: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

316 Perl pour les linguistes

Plus précisément, certaines données linguistiques sont actuellement diffusées ex-clusivement au format XML, comme le lexique morphosyntaxiqueMorphalouou descorpus de textes annotés comme ceux de laFReeBank. Leur exploitation nécessite dèslors la mise en place de programmes spécifiques qui seront présentés ici. XML estégalement une solution à considérer dès lors que l’on souhaite diffuser certaines don-nées, comme des annotations supplémentaires sur un corpus existant, ou des lexiquesenrichis. La production de telles données passe également par l’emploi de techniquesspécifiques de programmation en Perl.

Nous allons voir dans cette partie comment exploiter et produire des données auformat XML. Nous présenterons tout d’abord les principes des documents XML :leurs principales caractéristiques et les éléments qui lescomposent. En nous basantsur différents types de données nous verrons ensuite les techniques fondamentalespermettant leur exploitation par des programmes Perl en utilisant les modules adaptés.

AVERTISSEMENT.– Les techniques présentées dans ce chapitre font appel à des no-tions complexes de la programmation en Perl, et notamment aux structures de donnéescomplexes. Celles-ci sont présentées plus en détail en annexe A4. La manipulation dedonnées au format XML nécessite de plus l’installation de modules Perl supplémen-taires, ces modules étant indiqués au fur et à mesure dans le présent chapitre.

9.1.1. Concepts et structure d’un document XML

Un document XML est avant tout représenté par du texte : toutel’informationcontenue y est codée par des séquences de caractères. Ainsi,pour un document commeun ouvrage, on y trouvera le contenu du document, mais aussi des informations supplé-mentaires indiquant la structure de ce document (quel est son titre, son auteur, quellessont ses différentes parties et sous-parties, etc.), et le statut des différents élémentsqui le composent (notes, références, citations, etc.). Mais il est également possible d’yajouter toutes les informations que le rédacteur juge pertinentes (annotations, com-mentaires, etc.).

9.1.1.1.Premier exemple : balises et éléments

Un exemple simple de document XML est présenté en figure 9.1, comprenant unestructuration d’un extrait desContes de la Bécasse:

<?xml version="1.0" encoding="iso-8859-1"?><ouvrage>

<entete><titre>Les Contes de la Bécasse</titre><auteur>Guy de Maupassant</auteur><annee>1883</annee>

</entete>

Page 309: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Manipulation de données au format XML 317

<introduction><par>Le vieux baron des Ravots avait été pendant quarante an s leroi des chasseurs de sa province. Mais, depuis cinq à six anné es,une paralysie des jambes le clouait à son fauteuil, et il nepouvait plus que tirer des pigeons de la fenêtre de son salon o u duhaut de son grand perron.</par>...

</introduction><nouvelle>

<titre>Ce cochon de Morin</titre><partie num="1">

<par>"Ça, mon ami, dis-je à Labarbe, tu viens encore de prono ncerces quatre mots, "ce cochon de Morin". Pourquoi, diable, n’a i-jejamais entendu parler de Morin sans qu’on le traitât de "coch on"? "</par>

</partie>...

</nouvelle><nouvelle>

...</nouvelle>

</ouvrage>

Figure 9.1. Structuration XML d’un extrait desContes de la Bécasse

La première ligne de cet extrait indique que les lignes suivantes constituent undocument au format XML, et que le codage des caractères utilisé dans le documentestiso-8859-1(ouLatin1) (voir annexe A2).

Cet extrait contient des segments de texte tels qu’on les trouve dans une version entexte brut, mais également des séquences spécifiques au format XML, comprises entreles caractères< et>, comme<titre> , <par> , etc. Ces séquences de caractères sontappeléesbalises(tagsen anglais) et servent à spécifier la structure du document. Lesbalises sont principalement de deux types :

– des balises ditesouvrantes, comme<ouvrage> , <en_tete> , etc., qui in-diquent le début d’une partie du document. Le nom de la baliseindique le statut decette partie ;

– des balises ditesfermantes, comme</ouvrage> et </en_tete> qui in-diquent la fin de cette même partie. Elles ont la même forme queles balises ouvrantescorrespondantes, mais commencent par</ au lieu de<.

Ces balises délimitent des parties du document, et définissent ce que l’on nommeen XML deséléments. Il est possible comme on le voit qu’un élément contiennentd’autres éléments. Ainsi, la structure globale de cet extrait est la suivante :

– il s’agit au plus haut niveau d’unouvrage ;

– cet ouvrage est constitué d’uneentête , d’uneintroduction et d’une sériedenouvelle (s) (dont seul le début de la première est indiqué dans l’extrait) ;

Page 310: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

318 Perl pour les linguistes

– l’entête se décompose en untitre , un auteur et uneannee (il est recom-mandé d’orthographier les noms d’éléments sans accents) ;

– le contenu de ces trois derniers éléments est un segment de texte correspondantaux champs identifiés par les balises : le titre de l’ouvrage est donc le texte comprisentre<titre> et </titre> ;

– l’introduction est découpée en paragraphes (par ) et un paragraphe est simple-ment un segment de texte ;

– une nouvelle possède un titre, indiqué en utilisant à nouveau un élémenttitre :il utilise la même balise que le titre de l’ouvrage, mais son emplacement au sein del’élémentnouvelle évite toute confusion avec le titre de l’ouvrage ;

– une nouvelle est décomposée enpartie s, et chaque partie est définie par unnuméro (num). Ce numéro est indiqué à l’intérieur de la balise<partie> par ceque l’on nomme unattribut. Un attribut a la forme générique suivante :nom ="valeur" (on utilise des guillemets simples ou doubles pour délimiter la valeur)et permet d’associer des propriétés à un élément autrement qu’en y insérant un seg-ment de texte ;

– une partie est décomposée en paragraphes de la même façon que l’introduction.

Les noms de balises sont des chaînes arbitraires, décidées par le créateur du docu-ment. Toutefois, dans le cas où un document répond à une normespécifique, ces nomssont fixés par la norme en question.

9.1.1.2.Structure arborescente d’un document XML

Cette description illustre la réalité sous-jacente de toutdocument XML, qui estcelle d’une structure arborescente : chaque élément correspond au nœud d’un arbreconceptuel, dont la racine correspond à la totalité du document et dont les nœudsterminaux (ou feuilles) sont constitués du contenu textuel.

La figure 9.2 page 319 représente l’arbre correspondant à l’extrait desContes dela Bécasse.

Chaque élément du document correspond à un nœud de l’arbre. Les éléments tex-tuels sont également représentés par des nœuds d’un type particulier (leur contenu estindiqué en italiques dans la figure). La relation hiérarchique représentée par cet arbreest celle de l’inclusion des éléments du document. L’ordre des éléments dans le docu-ment est également représenté : les éléments successifs situés à un même niveau étantordonnés de gauche à droite.

Il est important de considérer à chaque instant que le document a une telle struc-ture, puisque c’est celle qui permettra la manipulation desdifférents éléments, commenous le verrons dans les programmes d’analyse et de manipulation.

Page 311: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Manipulation de données au format XML 319

<par>

<partie><titre>

<nouvelle>

<par><par><annee><titre>

<introduction>

<ouvrage>

<partie>

<par>

"Ça, mon ami

de Morin

Ce cochon

baron...

Le vieux1883

Maupassant

Guy de

la Bécasse

Les contes de

dis−je à..."

...

...

<auteur> ... ...

<entete>

Figure 9.2. Arbre XML desContes de la Bécasse

9.1.1.3.Autres notions

Certaines notions courantes de XML ne sont pas exemplifiées dans ce premierextrait, mais doivent cependant être connues avant d’aborder des données réelles.

9.1.1.3.1. Balises vides

En plus des balises ouvrantes et fermantes, il est possible de rencontrer dans undocument XML desbalises vides, qui n’ont aucun contenu. Ces balises servent gé-néralement à indiquer dans un document la présence d’un élément non textuel (uneimage, un tableau, etc.) ou à marquer dans un discours un élément extra-linguistique(une pause, un geste, un commentaire, etc.). Elles se notentde la façon suivante :

<pause/>

Une barre oblique est placée juste avant le caractère>. Une balise vide peut pos-séder des attributs, comme par exemple :

<pause duree="courte"/>

Ce type de balise peut être vu comme étant à la fois une balise ouvrante et unebalise fermante. Elle est logiquement équivalente à la séquence suivante :

<pause duree="courte"></pause>

9.1.1.3.2. Eléments mixtes

Dans certains types de documents, il est possible de rencontrer des éléments conte-nant à la fois du texte et d’autres éléments. On parle alors d’élément mixte. Ils sont cou-ramment utilisés pour marquer des éléments de discours dansdes documents annotés.

Page 312: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

320 Perl pour les linguistes

Par exemple, on peut concevoir de marquer les noms propres dans un paragraphe enutilisant des balises<np> :

<par>"Ça, mon ami, dis-je à <np>Labarbe</np>, tu viens enco re de

prononcer ces quatre mots, "ce cochon de <np>Morin</np>". P ourquoi,

diable, n’ai-je jamais entendu parler de <np>Morin</np> sa ns qu’on

le traitât de "cochon" ? "</par>

Le contenu de l’élément mixtepar est dans ce cas une suite d’alternances entredu texte et des élémentsnp .

9.1.1.3.3. Métacaractères et entités

Puisque les éléments structurants d’un document XML s’expriment par des balisesutilisant les caractères< et >, ces caractères ne peuvent apparaître tels quels dans lecontenu textuel. Le cas échéant, ils apparaissent sous la forme d’une séquence qui leurfait référence appeléeentité, et plus précisément :

– &lt; pour< (acronyme deless than) ;

– &gt; pour> (acronyme degreater than) ;

– comme ces notations donnent un statut de métacaractère au caractère&, il doitlui-même être exprimé par la séquence :&amp; (diminutif deampersand).

De plus, les valeurs des attributs devant être exprimées entre guillemets (simples oudoubles), une valeur d’attribut ne peut contenir directement un tel caractère et ceux-cidoivent être signifiés en utilisant les entités suivantes :

– &apos; pour le guillemet simple (’ ouapostrophe) ;

– &quot; pour les guillemets doubles (" ouquote).

Les entités permettent également d’exprimer par une telle notation certains carac-tères difficiles à manipuler (comme certains symboles ou logos). On utilise dans cecas leur numéro de code Unicode dans une séquence du type&#2354; . Pour plus dedétails, consulter l’annexe A2.

Il est enfin possible de définir des entités arbitraires propres à un document ou àune classe de document. Cela permet par exemple d’alléger lecode XML quand unsegment de texte (ou une partie de structure XML) se répète fréquemment.

Toutefois, les méthodes de manipulation des données XML traitent automatique-ment ce type de notation ; l’utilisateur des techniques présentées dans la suite de cechapitre n’a généralement pas à s’en préoccuper.

Page 313: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Manipulation de données au format XML 321

9.1.1.3.4. Bonne formation d’un document

La logique de XML et la structure arborescente d’un documentimpliquent quel’utilisation des balises suive un ensemble de règles. L’exploitation des données d’undocument par un programme nécessite que celui-ci soitbien formé, autrement dit qu’ilsoit possible de construire un arbre logique à partir du fichier XML. Les principalesrègles sont les suivantes :

– le document doit avoir comme première ligne une déclaration XML ;

– le document doit être entièrement contenu dansun seulélément de plus hautniveau, appeléélément racine;

– à toute balise ouvrante (respectivement fermante) doit correspondre une balisefermante (respectivement ouvrante), et une seule ;

– deux éléments ne peuvent pas se chevaucher. Par exemple, laséquence de balisesci-dessous est mal formée :<a><b></a></b>

Un document mal formé ne peut généralement pas être exploité, et entraîne uneerreur lors de son traitement. Cette erreur est systématiquement indiquée par un mes-sage spécifique lors de l’application d’une des techniques présentées dans la suite dece chapitre.

9.1.1.3.5. Lignes et espaces

Les balises XML ont pour but d’indiquer la structure logiqued’un document. Cesont donc elles qui en explicitent la segmentation. Dans un fichier au format XML, lescaractères de fin de ligne et les espaces sont généralement inutiles lorsqu’ils servent àséparer des balises, et ne seront généralement pas perçus lors d’un traitement automa-tisé. Ainsi, les deux séquences suivantes sont logiquementéquivalentes :

1 : <a><b></b></a>

2 : <a><b></b>

</a>

La seconde séquence a toutefois comme avantage d’expliciter visuellement lastructure arborée exprimée par la logique des balises, doncde rendre plus lisible ledocument lorsque celui-ci est visualisé par un utilisateur.

Ces caractères sont toutefois pertinents lorsqu’ils apparaissent au sein de segmentsde texte.

Page 314: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

322 Perl pour les linguistes

9.1.1.3.6. Instructions de traitement

Un document XML étant avant tout destiné à être manipulé par un programmeinformatique, un ensemble d’instructions peut être rencontré (essentiellement dans lespremières lignes). Nous ne détaillerons pas toutes ces instructions, mais voici les pluscourantes :

<!DOCTYPE docbook system "docbook.dtd">

Cette balise indique que le document dans laquelle elle apparaît correspond à un mo-dèle de document particulier (icidocbook) et répond à une logique spécifique qui estdécrite dans un fichier indiqué dans la balise (icidocbook.dtd) :

<?xml-stylesheet type="text/css" href="exemple.css" ?>

Cette instruction indique que le document dispose d’une feuille de style associée (oustyle sheet). Une feuille de style est un document externe (iciexemple.css) précisantles caractéristiques typo-dispositionnelles du contenu des différents éléments. Ces in-dications ne peuvent être exploitées que dans un environnement logiciel adéquat. Ilexiste plusieurs types de feuilles de styles, dont les feuilles de style en cascade (Cas-cading Style Sheetou CSS) et XSL(eXtensible Stylesheet Language). Ces aspects deXML, liés essentiellement à la visualisation d’un document, ne seront pas abordés ici :

<!-- Commentaire -->

Cette expression correspond à un commentaire. Comme pour les commentaires dansle code d’un programme, le contenu de cette balise ne sera paspris en compte lors dutraitement du document.

Il est relativement aisé de repérer de telles instructions,puisqu’elles sont contenuesdans des balises marquées de façon spécifique, notamment en utilisant les délimiteurs<? et<! . Si leur exploitation ne rentre pas dans le cadre de ce chapitre, les techniquesprésentées ici ignorent simplement ces instructions : leurprésence dans un documentn’entraîne aucun problème spécifique.

9.1.2. Exemples de données en XML

L’exemple utilisé précédemment ne correspond pas exactement à une donnéeréelle, mais a été forgé pour illustrer les principales notions. Les véritables donnéeslinguistiques au format XML sont généralement plus complexes et d’une grande va-riété. Nous présentons ci-dessous deux exemples de documents dont le traitement pardes programmes Perl est détaillé par la suite.

Page 315: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Manipulation de données au format XML 323

9.1.2.1.Textes structurés : dialogue annoté du corpus Ozkan

La principale utilisation en linguistique des données au format XML est l’annota-tion de textes. Comme on a pu le voir dans l’exemple forgé ci-dessus, il est en effetpossible d’expliciter les différentes parties d’un texte et la nature de certains de seséléments. XML est également très utilisé pour exprimer le lien entre des segments detexte et des informations extra-linguistiques, comme c’est le cas dans la transcriptionde données orales.

Un exemple de telles données est le corpusOzkan, mis à disposition sur laFRee-bank3. Nous remercions Susanne Alt, Jean Caelen et Nadine Ozkan pour nous avoirpermis de rediffuser ce corpus et de l’inclure dans l’environnement de travail (voirparagraphe 1.5.1.11 page 62).

Ce corpus est constitué de dialogues entre un instructeur (noté I) et un mani-pulateur (M) d’un logiciel de dessin. Les informations disponibles dans ce corpusconcernent à la fois les échanges langagiers entre les deux locuteurs et les gestes qu’ilseffectuent. La structure XML utilisée permet donc de distinguer les interactions ver-bales (en indiquant le locuteur, le texte prononcé, et des commentaires indiquant letype d’échange) et les actions physiques (indiquant le geste effectué et qui le réalise).De plus, les expressions référentielles sont indiquées, lecas échéant, dans le texte dudialogue.

Un extrait d’un tel dialogue, disponible dans le fichierC11ballon-ref-dial.xmlestprésenté en figure 9.3.

<?xml version="1.0" encoding="UTF-8"?><dialogue xmlns:xsi="http://www.w3.org/1999/XMLSchem a-instance">

<head><coding_info>

<author>Julien Jacquot</author><date>00-03-11</date>

</coding_info><dialogue_info>

<couple instructor="Elise" manipulator="Daniel"strategy_manipulator="prudent">C11</couple>

<figure>ballon</figure></dialogue_info>

</head><body>

<verbal_action id="xsd:1" who="I"><seg>qui est ce qui fait ça là</seg><comment type="speech_act">question introduite</comme nt>

</verbal_action><verbal_action id="xsd:2" who="M">

<seg>ah, moi je fais rien</seg><comment type="speech_act">information en réponse</com ment>

</verbal_action>

3. http://freebank.loria.fr/ .

Page 316: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

324 Perl pour les linguistes

<verbal_action id="xsd:3" who="I"><seg>ah c’est moi</seg><comment type="speech_act">information en initiative</ comment>

</verbal_action><kinesic_action id="xsd:4" who="I">

<global_description>geste de saisie</global_descripti on><comment type="speech_act">échec</comment>

</kinesic_action><verbal_action id="xsd:5" who="M">

<seg>tu veux faire quoi </seg><comment type="speech_act">question introduite</comme nt>

</verbal_action><verbal_action id="xsd:6" who="I">

<seg>ben je veux prendre <de id="re:1" det="NP_def">la bar reverticale</de>, et <de id="re:2" det="PR_pers">la</de>monter</seg>

<comment type="speech_act">information en réponse à vale ur derequête</comment>

</verbal_action><verbal_action id="xsd:7" who="I">

<seg>tu pourrais<de id="re:3" det="PR_pers"> le </de>fai re</seg><comment type="speech_act">question oui/non</comment>

</verbal_action>...

</body></dialogue>

Figure 9.3. Extrait d’un dialogue du corpus Ozkan

Ce document décrit donc un dialogue, comme une suite d’actions (verbales ougestuelles) commentées. Le détail de la structure est présenté lors de son exploitationdans les paragraphes 9.2.2.2 et 9.2.3.

9.1.2.2.Lexiques structurés :Morphalou

Un autre type d’utilisation des possibilités de XML concerne les données lexicales.Très utilisé en lexicographie, XML permet en effet de structurer les différents champsde la description d’une entrée lexicale.

Le lexique Morphalou (http://www.cnrtl.fr/morphalou/ ) est une res-source XML présentant les caractéristiques morphologiques de plus de 500 000formes, regroupées par lemme (voir 1.5.2.3). Un extrait de la structure du lexiqueest présenté en figure 9.4.

<lexicalEntrylemma="lexique"grammaticalCategory="commonNoun"grammaticalGender="masculine" >

<inflectionGroup><inflection

orthography="lexique"grammaticalNumber="singular" />

<inflectionorthography="lexiques"

Page 317: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Manipulation de données au format XML 325

grammaticalNumber="plural" /></inflectionGroup>

</lexicalEntry>

<lexicalEntrylemma="morphologique"grammaticalCategory="adjective" >

<inflectionGroup><inflection

orthography="morphologique"grammaticalGender="masculine"grammaticalNumber="singular" />

<inflectionorthography="morphologique"grammaticalGender="feminine"grammaticalNumber="singular" />

<inflectionorthography="morphologiques"grammaticalGender="masculine"grammaticalNumber="plural" />

<inflectionorthography="morphologiques"grammaticalGender="feminine"grammaticalNumber="plural" />

</inflectionGroup></lexicalEntry>

Figure 9.4. Extrait du lexique Morphalou

L’ensemble des informations est ici présenté sous forme d’attributs, qu’il s’agissedes formes, lemmes, catégories grammaticales ou des traitsmorphologiques.

Chaque entrée lexicale est représentée par un élémentlexicalEntry , où sontindiqués le lemme, la catégorie et les traits indépendants de la flexion (comme le genrepour les noms). Chaque entrée lexicale possède également une liste de formes fléchies(inflection ) regroupées dans un élémentinflectionGroup . C’est dans ceséléments vides que se trouvent les chaînes correspondant aux formes fléchies et auxtraits flexionnels (également sous forme d’attributs). Nous présentons en 9.2.2.1 unprogramme permettant l’exploitation de ces données.

9.1.3. Traitements spécifiques nécessaires

Comme on peut le voir dans les exemples précédents, l’exploitation de donnéesau format XML nécessite un ensemble de traitements spécifiques. S’il est possibled’aborder de tels fichiers de façon traditionnelle, en les parcourant ligne par ligneet en utilisant des expressions régulières pour repérer lesdifférents éléments, cettetechnique est très fortement déconseillée car elle implique de gros efforts pour le pro-grammeur, notamment :

– la prise en compte du codage des caractères exprimés dans laligne de déclarationXML en début de fichier ;

Page 318: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

326 Perl pour les linguistes

– la transformation des expressions codant les métacaractères ;

– le repérage des différentes balises (ouvrantes, fermantes, vides) et des attributsqui y correspondent ;

– la gestion de la souplesse de découpage des différentes balises (et notamment lefait que des fins de ligne peuvent apparaître ou non entre les balises, voire au sein desbalises complexes).

La bonne solution consiste à utiliser des programmes et des modules génériqueseffectuant les tâches de bas niveau pour exploiter ces données. Le programme fonda-mental pour cette exploitation est unparseurXML, c’est-à-dire un programme externedont le rôle est justement de gérer les situations évoquées ci-dessus.

Le parseur n’est toutefois pas utilisable directement : sonrôle est simplement dedécouper les différents éléments et de les communiquer à un programme qui doitles exploiter. Cette communication est elle-même réaliséepar des modules Perl spé-cifiques, qui permettent notamment d’avoir directement accès au nom des élémentsprésents dans le document, à leurs attributs (avec leurs valeurs) et à leur contenu tex-tuel le cas échéant. Les modules Perl que nous présentons ci-dessous sont fournis avecun parseur : son installation et les modalités techniques deson utilisation ne sont pasà la charge du programmeur.

La part de travail restant au programmeur est d’exploiter lastructure logique dudocument analysé et d’effectuer le traitement de contenu souhaité.

Cette appel à des fonctionnalités existantes est égalementvalable lorsque l’on sou-haite produire un document XML en sortie d’un programme. En partant de donnéesreprésentées en mémoire, il est en effet possible de confier la production des balises etentités XML à un module Perl dédié, là encore en ne laissant à la charge du program-meur que l’ordonnancement logique des opérations.

Avant de rentrer dans le détail de leur manipulation, nous allons présenter les prin-cipaux modules Perl disponibles.

9.1.4. Modules Perl disponibles

Les différents modules présentés ici ne sont qu’une sélection de l’éventail proposépar le langage Perl. Il s’agit toutefois des modules les plusrépandus et les plus utilisésqui permettent d’effectuer la plupart des opérations nécessaires à l’exploitation dedonnées linguistiques en XML.

Chacun de ces modules doit généralement être installé spécifiquement. Cette situa-tion peut varier en fonction des cas : la distributionActivePerlcomprend notamment

Page 319: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Manipulation de données au format XML 327

la plupart de ces modules par défaut. Dans le cas contraire, il peut être nécessaire deles installer en utilisant les procédures automatiques fournies avec Perl.

La liste des modules décrits par la suite sont :

– XML::Simple : ce module minimaliste d’analysede données XML est le plusfacile d’utilisation, mais ne permet pas la manipulation dedonnées complexes ou vo-lumineuses ;

– XML::Parser : ce module de manipulation moyennement complexe permetd’effectuer la totalité desanalyses; il s’agit généralement du choix par défaut ;

– XML::DOMest le module le plus sophistiqué pour l’analyseet correspond à uneapproche complexe nécessitant d’être familiarisé avec la manipulation de structuresarborescentes. Il permet également lamodificationd’un document XML ;

– XML::Writer est le module le plus simple pour laproductionde données enXML.

9.2. Analyse d’un fichier XML

Cette section détaille les techniques d’analyse d’un fichier au format XML quipermettent d’en exploiter le contenu. Les exemples présentés ici ne couvriront pastoutes les possibilités, mais pourront facilement être adaptés à d’autres traitements.

Il existe plusieurs possibilités techniques pour analyserun fichier XML. On peutidentifier deux types d’approches :

– la mise en mémoire de l’ensemble du document dans une structure de donnéescomplexe. Cette méthode est plus confortable puisqu’elle met automatiquement à dis-position du programmeur (via des modules Perl prêts à l’emploi) l’ensemble des don-nées à exploiter. La seule difficulté consiste alors à parcourir la structure de donnéesainsi obtenue. Toutefois, les programmes utilisant cette méthode sont très gourmandsen temps de calcul et en occupation de la mémoire : ils ne sont pas utilisables pourdes données massives (puisque tout le document est stocké enmémoire). Les modulesPerl correspondants sontXML::Simple etXML::DOM;

– le traitement par flux. Cette approche consiste à analyser le document en indi-quant les traitements à effectuer chaque fois qu’un élémentest rencontré. Dans ce cas,le parseur se contente de signaler au programme quand il rencontre, en parcourant ledocument, des balises ouvrantes ou fermantes, ou un segmentde texte. Le programmedoit alors indiquer quelle action réaliser en fonction de ces événements (sous la formede sous-programmes). Cette méthode est plus exigeante pourle programmeur, puis-qu’elle l’oblige notamment à mémoriser les informations disponibles en fonction deses besoins, mais elle est tout à fait adaptée au traitement de masses importantes dedonnées, puisque l’occupation en mémoire est minimale. Le moduleXML::Parserpermet d’utiliser cette méthode.

Page 320: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

328 Perl pour les linguistes

Rappelons que les modules Perl proposés ici effectuent les traitements de bas ni-veau nécessaires pour toute analyse d’un document XML, et notamment l’identifica-tion des balises, la récupération des valeurs des attributs, la gestion du codage descaractères et des entités.

9.2.1. Approche minimaliste :XML::Simple

Dans le cas où le document XML est simple et court, il est possible d’utiliser lemoduleXML::Simple , dont la manipulation est la plus directe. Ce module permetde construire une structure de données classique en Perl à partir du contenu du docu-ment. La structure de données obtenue est une structure de données complexe utilisantles références, dont les principes sont décrits en annexe A4.

Nous prendrons pour exemple de l’utilisation de ce module uncourt texte étiqueté(Les Contes de la Bécasse) mis au format XML suivant4 :

<?xml version="1.0" encoding="iso-8859-1"?><texte source="becass2.tag">

<phrase><mot num="1">

<forme>Le</forme><lemme>le</lemme><categorie>DET:ART</categorie>

</mot><mot num="2">

<forme>vieux</forme><lemme>vieux</lemme><categorie>ADJ</categorie>

</mot><mot num="3">

<forme>baron</forme><lemme>baron</lemme><categorie>NOM</categorie>

</mot>...

</phrase><phrase>

<mot num="19"><forme>Mais</forme><lemme>mais</lemme><categorie>KON</categorie>

</mot><mot num="20">

4. Ce document est produit à partir d’une sortie de l’étiqueteur TreeTagger en utilisant le pro-grammeconversion-tag-XML.plprésenté en 9.3.1.

Page 321: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Manipulation de données au format XML 329

<forme>,</forme><lemme>,</lemme><categorie>PUN</categorie>

</mot>...

</phrase>...</texte>

Figure 9.5. Extrait d’un texte étiqueté (Les Contes de la Bécasse) mis auformat XML

Ce type de document décrit untexte (avec comme attribut unesource) commeétant composé d’une suite dephrases. Chaquephraseest une suite demots. Chaquemot a comme attribut un numéro (num) et contient trois informations textuelles : uneforme, un lemmeet unecatégorie.

La structure de données Perl construite automatiquement par le moduleXML::Simple est la suivante :

"source" -> "becass2.tag","phrase" -> [ #liste des phrases

#première phrase"mot" -> [ #liste des mots

#premier mot de la première phrase"num" -> "1","forme" -> "Le","lemme" -> "le","categorie" -> "DET"

, #deuxième mot

"num" -> "2",... autres champs du deuxième mot

,...autres mots de la première phrase...

], #deuxième phrase

"mot" -> [ ...mots de la deuxième phrase... ]....autres phrases du texte....

]

Soit plus explicitement :

– la structure obtenue est une référence de hachage, qui correspond au contenu del’élément racinetexte (le nom de cet élément n’apparaît pas dans la structure) ;

Page 322: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

330 Perl pour les linguistes

– l’attribut source de l’élémenttexte , apparaît comme clé de ce hachage aveccomme valeur la chaînebecass2.tag;

– les élémentsphrase correspondent à une seule clé du hachage. Toutefois,comme il y a plusieurs éléments de ce type (le texte comporte plusieurs phrases),la valeur associée est un tableau (de phrases) ;

– les éléments du tableau associé àphrase correspondent donc chacun à unephrase, et sont des hachages. Chaque hachage a une clé unique, mot puisqu’il s’agitdu seul type d’élément contenu dans les élémentsphrase ;

– comme une phrase contient plusieurs mots, la valeur associée àmot dans chaquephrase est un tableau (de mots) ;

– chaque mot de ce tableau est décrit par un hachage dans lequel on trouve commeclé son attribut (num) et ses sous-éléments :forme , lemme et categorie ;

– comme chacun de ces éléments ne contient que du texte, sa valeur associée estsimplement son contenu textuel.

analyse-XML-simple.plprésenté ci-dessous est un programme permettant d’ana-lyser ce type de document en utilisantXML::Simple .

Listing 9.1 – analyse-XML-simple.plAnalyse d’un texte étiqueté au format XMLvia le moduleXML::Simple

1 use locale;2 use strict;3 use XML::Simple;4

5 if ($#ARGV != 0)6 die "Usage : ", $0, " fichier_xml\n";7

8 my $document = XMLin($ARGV[0]);9 my $source = $document->"source";

10 print "Fichier source : ",$source,"\n";11

12 foreach my $phrase (@$document->"phrase")13 print "---PHRASE---\n";14 foreach my $mot ( @$phrase->"mot" )15 print $mot->"num","\t";16 print $mot->"forme","\t";17 print $mot->"lemme","\t";18 print $mot->"categorie","\n";19 20

Ligne de commande :perl analyse-XML-simple.pl fichier_xml

Exemple :perl analyse-XML-simple.pl becass2.xml

Page 323: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Manipulation de données au format XML 331

Résultat (extrait) :Fichier source : becass2.tag

---PHRASE---

1 Le le DET:ART

2 vieux vieux ADJ

3 baron baron NOM

4 des du PRP:det

5 Ravots ravot NOM

6 avait avoir VER:impf

...

Détails du programme :

La fonction XMLin permet, pour un nom de fichier passé en paramètre,de construire la structure de données correspondantes, stockée dans la référence$document . Une fois cette structure remplie par le biais deXMLin , son exploi-tation est très simple :

– la source (stockée dans l’attributsource de la racine) est extraite et affichée.L’information est disponible dans la valeur associée à la clé sourcedu hachage réfé-rencé par$document , identifiée par l’expression$document->$source ;

– la liste des phrases est parcourue. Cette liste est contenue dans le ta-bleau associé à la cléphrasedans le hachage référencé par$document , soit@$document->"phrase" . A chaque nouvelle phrase un indicateur est af-fiché en sortie, puis la liste des mots de celle-ci est parcourue. La variable$phrasecontient une référence à un hachage, la liste des mots est le tableau associé à la clémot dans ce hachage ;

– pour chaque mot de la phrase, sont affichés sur une ligne son numéro, sa forme,son lemme et sa catégorie. Ces trois informations sont les valeurs associées aux cléscorrespondantes dans le hachage référencé par$mot .

Principes généraux et limitations :

Comme on peut le voir dans le code de ce programme, l’utilisation du moduleXML::Simple est relativement aisée. Il suffit simplement de parcourir lastructurede données complexe en utilisant les mécanismes classiquesde Perl. En résumé, lastructure de données obtenue par l’utilisation de ce moduleest construite en appliquantles principes suivants :

– à chaque élément correspond un hachage dont la clé est le nomde l’élément etla valeur une représentation de son contenu ;

– si plusieurs éléments d’un même type se trouvent les uns à lasuite des autres(sous forme de liste), alors la valeur associée au nom de l’élément sera un tableau,chaque élément de la liste étant stocké dans les cellules du tableau ;

Page 324: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

332 Perl pour les linguistes

– si un élément possède des attributs, ils sont représentés de la même façon quedes sous-éléments, donc à l’aide d’un hachage dont les clés sont les noms des attributset les valeurs associées les valeurs correspondantes des attributs ;

– si un élément ne contient que du texte, alors la valeur associée est le contenutextuel de cet élément ;

– si un élément ne contenant que du texte possède des attributs, son contenu tex-tuel est stocké dans le hachage correspondant à l’élément, associé à la clé spécifiquecontent .

Toutefois, l’utilisation de ce module est très limitée, et généralement inapplicableà des documents XML complexes. Les principales limites sontles suivantes :

– si le document est volumineux, le temps passé par le programme pour construirela structure de données peut être excessivement long. Au-delà de quelques méga-octetsde données cette approche est inapplicable ;

– si la structure est très complexe, et si l’arbre du documentest très profond, l’uti-lisation de cette méthode devient très lourde. Il est en effet nécessaire de parcourirl’arbre depuis sa racine pour accéder aux éléments de bas niveau, ce qui entraîne lamise en place d’une boucle ou d’un parcours de hachage par niveau intermédiaire ;

– si le contenu de certains éléments est mixte, ou présente une alternance entredes éléments de type différents, il n’est pas possible de connaître l’ordre exact de cesderniers, les éléments d’un même type étant répartis dans des tableaux distincts.

Malgré ces limitations importantes, le moduleXML::Simple est notamment uti-lisé pour l’analyse des données fournies par certains de moteurs de recherche sur leWeb, comme c’est le cas pour les programmes présentés au chapitre 10.

Pour les autre situations, face à des documents volumineux ou complexes, il estpar contre nécessaire d’employer une des deux méthodes présentées ci-dessous.

9.2.2. Approche par flux (à la SAX) :XML::Parser

La méthode présentée ici correspond à un traitement par flux d’un document XML.Le modèle le plus connu de ce type d’approche estSAX(Simple API for XML). Lesfonctionnalités offertes par cette méthode sont très réduites, ce qui impose au pro-grammeur utilisant cette approche de gérer lui-même l’ensemble des informationsdisponibles, et de ne stocker en mémoire que celles qui sont pertinentes pour son ap-plication. Cette approche convient donc particulièrementaux documents volumineux,puisqu’elle n’entraîne pas de surcoût de mise en mémoire.

Plus précisément, les modules implémentant cette méthode proposent un objet pré-défini correspondant à unparseurXML. Ce parseur est capable de découper le flux

Page 325: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Manipulation de données au format XML 333

d’entrée du fichier XML et d’y repérer les balises ouvrantes (avec leurs attributs), lesbalises fermantes, et les segments de texte. Il est également capable de déclencherun traitement spécifique dans chacune de ces situations. Cestraitements, à la chargedu programmeur, sont baptisésrécepteurs(ou handlers), et sont tout simplement desfonctions Perl. Chaque nouvelle balise ou segment de texte lu par le parseur entraînel’exécution du récepteur correspondant. Il est important de noter que le parseur lui-même ne mémorise absolument aucune information et ne propose comme données àtraiter au récepteur que le contenu de l’élément courant du flux. La gestion de l’arbo-rescence XML du document est entièrement à la charge du programmeur : cet aspectparfois laborieux est la contre-partie de la légèreté et de l’efficacité de cette technique.

9.2.2.1.Premier exemple : analyse du lexique Morphalou

Nous allons présenter un exemple de traitement sur un document particulièrementvolumineux, le lexique morphologiqueMorphalou, contenant plus de 500 000 formesfléchies et stocké dans un fichier XML de plus de 70 méga-octets. La structure de celexique est présentée en 9.1.2.2.

Le programme extractions-noms-morphalou.plse base sur le moduleXML::Parser et a pour but l’extraction de l’ensemble des formes fléchiesnominales de Morphalou, en les présentant en sortie accompagnées de leur lemme etde leurs traits morphologiques (genre et nombre).

Listing 9.2 – extraction-noms-morphalou.plExtraction des formes nominales du lexiqueMorphalou

1 use strict;2 use locale;3 use XML::Parser;4

5 if ( $#ARGV != 0 ) 6 die "Usage : ", $0, " fichier_morphalou\n";7 8

9 my $parseur = new XML::Parser;10 $parseur -> setHandlers (11 Start => \&balise_ouvrante12 );13

14 my ( $categorie, $genre, $lemme );15

16 $parseur -> parsefile( $ARGV[0] );17

18 sub balise_ouvrante 19 my $p = shift @_;20 my $balise = shift @_;21 my %attributs;22 while ( $#_ >= 0 )23 my $cle = shift @_;24 my $valeur = shift @_;25 $attributs$cle = $valeur;

Page 326: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

334 Perl pour les linguistes

26 27

28 if ( $balise eq "lexicalEntry" )29 $categorie = $attributs"grammaticalCategory";30 if ($categorie eq "commonNoun")31 $lemme = $attributs"lemma";32 $genre = $attributs"grammaticalGender";33 34 35 elsif ( $balise eq "inflection" and36 $categorie eq "commonNoun" )37 print $attributs"orthography","\t",$lemme,"\t",38 $genre,"\t", $attributs"grammaticalNumber","\n";39 40

Ligne de commande :perl extraction-noms-morphalou.pl fichier_morphalou

Exemple :perl extraction-noms-morphalou.pl

C:\PPL\Lexiques\Morphalou_1.0.1.xml

Sous Unix, le chemin du fichier XML contenantMorphalouest :~/PPL/Lexiques/Morphalou_1.0.1.xml

Résultat (extrait) :aalénien aalénien masculine singular

aaléniens aalénien masculine plural

aba aba masculine singular

abas aba masculine plural

abaca abaca masculine singular

abacas abaca masculine plural

...

REMARQUE.– L’ordre dans lequel les noms sont affichés est celui dans lequel ils sontstockés dans le fichier source de Morphalou. Cela explique notamment qu’ils soientclassés suivant leur lemme et non leur forme, et que les mots comportant des caractèresaccentués soient classés sans localisation. Les traits morphologiques correspondantau genre et au nombre sont indiqués en anglais pour la même raison, puisqu’il s’agitd’informations extraites directement du fichier source.

Détails du programme :

Le traitement effectué par ce programme sur la structure du lexique est relative-ment simple :

Page 327: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Manipulation de données au format XML 335

– quand une baliselexicalEntry est trouvée, elle indique la catégorie de l’en-trée et, dans le cas d’un nom, son lemme et son genre (le tout sous forme d’attributs).Par contre, les formes fléchies n’y sont pas directement présentes. Il est donc néces-saire de stocker les trois informations disponibles dans des variables globales afin deles rendre accessibles pour une exploitation ultérieure ;

– quand une baliseinflection est trouvée, il suffit de vérifier si elle fait bienpartie d’un élémentlexicalEntry décrivant un nom (plus précisément, que ledernier élémentlexicalEntry rencontré correspondait à un nom). Si c’est le cas,on y trouve la forme fléchie et le nombre : il ne reste qu’à afficher ces informations,ainsi que le lemme et le genre qui ont été mémorisés lors du traitement de la baliselexicalEntry .

Le fonctionnement du programmeextraction-noms-morphalou.plrepose sur l’uti-lisation d’unparseur, c’est-à-dire d’un objet Perl de typeXML::Parser stocké dansla variable$parseur . Ce programme utilise deux méthodes associées à cet objet :

– la méthodesetHandlersspécifie les fonctions à exécuter à chaque fois que leparseur rencontre une balise (fermante ou ouvrante) ou un élément de texte. La syntaxeutilisée est celle d’un hachage dans lequel les clés correspondent aux événementsdétectés par le parseur, et les valeurs sont des références àdes fonctions définies dansle programme. Ici, seules les balises ouvrantes ou vides5 (mot-cléStart) entraînent untraitement. Ce dernier est réalisé par la fonctionbalise_ouvrante ;

– la méthodeparsefileeffectue véritablement le traitement du document une foisque les actions adaptées à chaque situation ont été indiquées.

L’ensemble des instructions concernant l’exploitation des données est contenudans le corps de la fonctionbalise_ouvrante . Le traitement qui y est réalisé estessentiellement local, mais doit s’appuyer sur des variables globales pour préserverune trace entre les différents appels.

Lors de l’analyse du document, la fonctionbalise_ouvrante est exécutée àchaque fois que le parseur rencontre une balise ouvrante (ouvide), quelle qu’elle soit.Ce faisant, il communique comme paramètres à la fonction dans l’ordre :

– l’objet de typeXML::Parser qui a déclenché cet appel. Cette information, in-utile dans notre cas, ne sert que dans les programmes complexes ou plusieurs parseurstravaillent simultanément ;

– une chaîne contenant le nom de l’élément ;

– une suite de couples (attribut, valeur) pour chaque attribut de l’élément en ques-tion.

5. Une balise vide est en effet considérée par le parseur commela succession d’une baliseouvrante et d’une balise fermante.

Page 328: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

336 Perl pour les linguistes

La fonctionbalise_ouvranterécupère dans un premier temps l’ensemble de cesinformations. Le premier paramètre ($p), bien qu’inutile, est extrait du tableau@_contenant les paramètres passés à la fonction. Le deuxième est stocké dans la va-riable locale$balise , et les attributs éventuels sont stockés dans le hachage local%attributs .

Le reste du traitement dépend du type de balise rencontré, comme cela a été vu pré-cédemment. Les seules balises concernées par ce programme sont lexicalEntry(qui fournit la catégorie de l’entrée, et pour le cas des nomsleur genre et leur lemme)et la baliseinflection qui fournit, pour les noms, leur forme et leur nombre. Dansle cas d’une baliselexicalEntry , la fonction se contente de stocker dans des va-riables globales la catégorie et les informations pertinentes dans le cas d’un nom.Ces informations ne sont utilisées que lorsqu’un élémentinflection est rencon-tré par la suite. Il est nécessaire d’utiliser ces variablesglobales puisque la notion dehiérarchie XML est absente explicitement du traitement. Tout le traitement s’appuiesimplement sur le fait que lorsque l’on rencontre un élémentde typeinflection ,les informations sur l’entrée sont celles qui ont été fournies par le dernier élémentlexicalEntry rencontré.

Le programmemorphalou2grace.pl, permettant de présenter le lexique Morpha-lou dans un format tabulé utilisant le jeu d’étiquettes GRACE (présenté en 1.5.2.8page 70) utilise les mêmes techniques que le programme décrit ici.

Le programmeextraction-noms-morphalou.pln’utilise qu’une partie très res-treinte des fonctionnalités du moduleXML::Parser , et ne s’appuie notamment quesur les balises ouvrantes sans traiter des segments de texte. Nous détaillons ci-dessousun second programme qui présente les autres fonctionnalités de cette technique.

9.2.2.2.Second exemple : extraction du texte d’un dialogue du corpusOzkan

Dans ce second exemple nous présentons un programme d’extraction du texte dudialogue contenu dans un fichier du corpus Ozkan, présenté enfigure 9.3 (page 324).

Pour extraire le texte du dialogue, il faut repérer les répliques marquées par lesbalisesverbal_action , qui indiquent notamment l’identifiant du locuteur, puisau sein des élémentsseg le texte lui-même. Ce texte peut être trouvé directementsous ce dernier élément, mais aussi au sein de sous-éléments, comme les expressionsréférentielles (de). Dans ce cas, le texte est découpé en plusieurs segments et doit êtrereconstitué au final sans les annotations. Le segment de texte n’est considéré commecomplet que lorsque l’élémentsegest terminé, comme le signale la balise fermantecorrespondante.

Page 329: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Manipulation de données au format XML 337

Listing 9.3 – extraction-Ozkan-flux.plExtraction du texte d’un dialogue du corpus Ozkanvia un traitement par flux

1 use locale;2 use strict;3 use XML::Parser;4

5 if ( $#ARGV!=0 )6 die "Usage : ", $0, "fichier_xml\n";7 8

9 my $parseur = new XML::Parser;10 $parseur -> setHandlers (11 Start => \&balise_ouvrante,12 End => \&balise_fermante,13 Char => \&segment_texte14 );15

16 my ( $segment, $segment_en_cours, $locuteur );17 $parseur->parsefile( $ARGV[0] );18

19 sub balise_ouvrante 20 my $p = shift @_;21 my $balise = shift @_;22 my %attributs;23 while ( $#_ >= 0 )24 my $cle = shift @_;25 my $valeur = shift @_;26 $attributs$cle = $valeur;27 28

29 if ( $balise eq "verbal_action" )30 $locuteur = $attributs"who";31 32 elsif ( $balise eq "seg" )33 $segment = "";34 $segment_en_cours = 1;35 36 37

38 sub segment_texte 39 my $p = shift @_;40 my $texte = shift @_;41 if ( $segment_en_cours ) 42 $segment = $segment . $texte;43 44 45

46 sub balise_fermante 47 my $p = shift @_;48 my $balise = shift @_;49 if ( $balise eq "seg" )50 $segment =~ s/\n//g;51 $segment =~ s/\s\s+/ /g;52 print $locuteur, " : ", $segment,"\n";53 $segment_en_cours = 0;54 55

Page 330: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

338 Perl pour les linguistes

Ligne de commande :perl extraction-Ozkan-flux.pl fichier_Ozkan

Exemple :perl extraction-Ozkan-flux.pl C11ballon-ref-dial.xml

Résultat (extrait) :I : qui est ce qui fait ça là

M : ah, moi je fais rien

I : ah c’est moi

M : tu veux faire quoi

I : ben je veux prendre la barre verticale, et la monter

I : tu pourrais le faire

Détails du programme :

A la différence du programmeextraction-noms-morphalou.pl, extraction-Ozkan-flux.pl utilise plusieurs types d’évènements repérés par le parseur XML. Au total, desrécepteurs sont attachés aux évènements suivants :

– Start : une balise ouvrante ou vide comme il a été vu dans le programmeextraction-noms-morphalou.pl;

– End : une balise fermante ou vide. Les paramètres passés à la fonction corres-pondante sont identiques à ceux d’une balise ouvrante, moins les attributs ;

– Char : un segment de texte. Les paramètres passés à la fonction sont : le parseuret le contenu de ce segment de texte (en codageUTF-8). Pour un même segment detexte, il peut arriver que celui-ci soit découpé arbitraitrement par le parseur en plu-sieurs appels à la fonction correspondante (indépendamment du découpage expliciteréalisé par les balises). Il est donc absolument nécessairede stocker en mémoire lessegments au fur et à mesure en les concaténant, et de ne considérer que le segmentn’est complet que lorsqu’une balise fermante est rencontrée.

Ce programme définit donc trois récepteurs, correspondant aux événementsStart,End et Char :

– balise_ouvrante fonctionne de la même façon que dansextraction-noms-morphalou.pl, et se concentre sur deux types d’éléments. Lorsqu’une balise ou-vranteverbal_action est rencontrée, elle permet d’identifier le locuteur (attri-but who). Lorsqu’une balise ouvranteseg est rencontrée, il est nécessaire de pré-parer l’extraction du texte qui sera trouvé dans cet élément. La variable globale$segment_en_cours est positionnée à 1 pour indiquer que les prochains seg-ments de texte rencontrés doivent être stockés dans la variable globale$segmentqui est donc initialisée ;

– segment_texte est déclenchée lorsque le parseur rencontre un segment detexte (celui-ci est passé en paramètre par le parseur à la fonction, et est stocké dans la

Page 331: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Manipulation de données au format XML 339

variable$texte ). Pour savoir si le segment en question est à prendre en compte, lavariable$segment_en_cours est examinée. Si elle a une valeur non nulle (doncune valeur de vérité vraie), alors le segment actuel est situé dans un élémentseg , etle texte est stocké à la suite de la variable$segment . Il faut noter que les élémentsde texte situés dans les éléments de typede sont aussi pris en compte, puisqu’ils sesituent à l’intérieur d’un élémentseg ;

– balise_fermante est déclenchée à chaque fois que le parseur rencontre unebalise fermante quelle qu’elle soit. Le seul événement de cetype qui nous intéresseici est la fin d’un élémentseg , qui indique également la fin d’un segment textuel.Celui-ci peut alors être affiché, son contenu étant stocké dans la variable$texte .Une suppression des éventuelles fins de ligne et des espaces superflus est réalisée aupréalable. Le locuteur est également affiché en sortie, tel qu’il avait été identifié lorsdu traitement de la dernière balise ouvranteverbal_action .

Comme on peut le voir dans ces deux exemples, l’approche par flux impose auprogrammeur de mémoriser dans des variables globales les informations disponiblesau fur et à mesure du traitement du document. Il est en effet impossible, lorsqu’unélément est traité par le parseur, de connaître autrement saposition dans la structureXML globale. C’est justement ce type d’information que sontcapables de fournirles méthodes par construction d’arbre, dont l’utilisationest décrite dans la sectionsuivante.

9.2.3. Approche par construction d’arbre (à la DOM) :XML::DOM

La méthode présentée ici est une approche très classique en exploitation de don-nées XML, baptiséeDOM (Document Object Model). Cette méthode est la plus com-plète mais aussi la plus difficile à utiliser, puisqu’elle passe par la manipulation d’ob-jets complexes correspondant à l’ensemble de l’arbre XML. Un parseur DOM (commecelui qui est accessible par le moduleXML::DOM) est en effet conçu pour construireen mémoire une représentation complète de l’information contenue dans un documentXML et d’en proposer ensuite la manipulation par un ensemblede fonctionnalités pré-définies. A la différence de la structure construite parXML::Simple , l’arbre obtenun’est pas une structure de données classique de Perl, mais unobjet complexe dont lamanipulation passe par un ensemble de méthodes. Nous nous contenterons ici d’enexposer les principales.

Le principe général de la manipulation d’un document par DOMest le suivant :

– le parseur analyse l’intégralité du fichier et renvoie une structure correspondantà l’arbre XML du document ;

– cet arbre est composé de nœuds, chaque nœud correspondant àun élément XMLou à un segment de texte ;

Page 332: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

340 Perl pour les linguistes

– à partir d’un nœud quelconque, il est possible d’accéder aux nœuds qui luisont supérieurs dans la hiérarchie (nœudsparents, correspondant aux éléments quile contiennent), ou inférieurs (nœudsenfants, correspondant aux éléments ou au textequ’il contient), ou encore à ses nœudsfrères(situés au même niveau, que lui, autre-ment dit les autres enfants de son parent direct) ;

– il est également possible d’utiliser des méthodes prédéfinies permettant de trou-ver automatiquement dans l’arbre l’ensemble des nœuds correspondant à un typed’élément.

AVERTISSEMENT.– Le moduleXML::DOM fait appel de façon très massive à la pro-grammation objet en Perl. Il est donc important de bien connaître les notations corres-pondant à ce type de programmation et surtout d’avoir un accès direct et permanent àla documentation des objets manipulés (via la commandeperldocou la documentationen ligne du module).

L’exemple proposé réalise une analyse plus poussée d’un dialogue extrait du cor-pus Ozkan. Nous chercherons dans le programme présenté ici àextraire l’ensembledes expressions référentielles et à les afficher avec l’ensemble de leurs caractéristiques(identifiant, locuteur et type). Ces différentes informations étant situées à différentsendroits de l’arbre XML, leur extraction s’appuie sur un parcours d’arbre.

Listing 9.4 – expressions-Ozkan-DOM.plExtraction des expressions référentielles et de leurs caractéristiques d’un dialogue ducorpus Ozkanvia le moduleXML::DOM

1 use locale;2 use strict;3 use XML::DOM;4

5 if ( $#ARGV != 0 ) 6 die "Usage : ", $0, " fichier_xml\n";7 8

9 my $parseur = new XML::DOM::Parser;10 my $doc = $parseur->parsefile( $ARGV[0] );11

12 my @liste_noeuds_de = @$doc->getElementsByTagName("de ");13

14 foreach my $noeud_de ( @liste_noeuds_de )15 my $numero = $noeud_de->getAttribute("id");16 my $type = $noeud_de->getAttribute("det");17 my $expression = $noeud_de->getFirstChild->getNodeValu e;18 my $noeud_action_verbale =19 $noeud_de->getParentNode->getParentNode;20 my $locuteur = $noeud_action_verbale->getAttribute("wh o");21 print $numero, " (",$locuteur,") : ", $expression,22 " (", $type,")\n";23

Page 333: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Manipulation de données au format XML 341

Ligne de commande :perl expressions-Ozkan-DOM.pl fichier_Ozkan

Exemple :perl expressions-Ozkan-DOM.pl C11ballon-ref-dial.xml

Résultat (extrait) :re:1 (I) : la barre verticale (NP_def)

re:2 (I) : la (PR_pers)

re:3 (I) : le (PR_pers)

re:4 (M) : celle-là (PR_dem)

re:5 (M) : la (PR_pers)

re:6 (I) : la (PR_pers)

re:7 (I) : le rond (NP_def)

re:8 (M) : le petit (NP_def)

Détails du programme :

Comme pour le moduleXML::Parser , l’utilisation du moduleXML::DOMcommence par la création d’un parseur. Ce parseur ne nécessite aucune informationparticulière ; il est appliqué immédiatement sur le fichier de donnéesvia la méthodeparsefile. Le résultat de cette opération est l’arbre XML correspondant au document,ou plus exactement le nœud correspondant à la racine de cet arbre (stocké dans laréférence$doc ).

A partir de cette racine, la première opération consiste à extraire la liste des nœudscorrespondant aux éléments de typede , qui renvoient aux expressions référentiellesmarquées dans le document. La méthodegetElementsByTagNamepermet en effet,à partir d’un nœud donné, et pour un nom d’élément passé en paramètre, d’obtenirla liste de tous les nœuds de ce type situés sous ce nœud. Partant de la racine, nousobtenons dans le tableau@liste_noeuds_de l’ensemble des nœuds de ce typedans le document, dans leur ordre naturel.

Pour chacun de ces nœuds, les informations suivantes sont extraites :

– son numéro, qui est la valeur de l’attributid de l’élémentde . Cette informationest obtenue par la méthodegetAttribute appliquée au nœud, avec comme paramètrele nom de l’attribut ;

– son type, qui est stocké dans l’attributdet ;

– l’expression elle-même : celle-ci est en fait contenue dans le nœud de type textesitué immédiatement sous le nœudde . Pour l’obtenir, deux méthodes sont utilisées :getFirstChild renvoie le premier nœud enfant situé sous le nœud auquel elles’ap-plique. La méthodegetNodeValuepermet ensuite d’obtenir la chaîne correspondantau texte lui-même ;

Page 334: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

342 Perl pour les linguistes

– le locuteur ayant employé cette expression. Cette information se situe dans l’at-tribut who de l’élémentverbal_action qui contient l’élémentde . Toutefois, lastructure du document est telle que cette relation hiérarchique n’est pas directe, maispasse par un élément intermédiaire, de typeseg . Le nœudverbal_action n’estdonc pas le parent direct du nœudde , mais le parent de son parent. La méthodeget-ParentNode, qui permet pour un nœud d’obtenir son parent direct, est donc appliquéedeux fois. Une fois le nœud correspondant àverbal_action obtenu, le locuteurest accessible en tant qu’attribut comme nous l’avons vu précédemment.

Ce court exemple montre que le moduleXML::DOMpermet d’arpenter l’ensemblede l’arbre, en se basant sur les relations de parenté entre les nœuds. La liste desméthodes disponibles dans ce module étant très longue, nousnous contentons d’enlister les principales dans le tableau 9.1.

Méthode Paramètre Résultat DescriptiongetElementsByTagNamenom de l’élémentliste ensemble des nœuds corres-

pondant à un nom d’élémentsitués sous le nœud courant

getAttribute nom de l’attribut chaîne valeur de l’attribut indiqué dunœud courant

getParentNode aucun nœud nœud correspondant à l’élé-ment qui contient directementle nœud courant

getNodeName aucun chaîne nom de l’élément du nœudcourant, ou#textsi le nœud estde type texte

getChildNodes aucun liste liste des nœuds situés immé-diatement sous le nœud cou-rant

getFirstChild aucun nœud premier nœud (dans l’ordredu document) situé immédiate-ment sous le nœud courant

getNodeValue aucun chaîne contenu du nœud à conditionque celui-ci soit de type Texte

Tableau 9.1.Principales méthodes applicables aux nœuds pourXML::DOM

9.3. Production de données au format XML

L’autre versant de la manipulation de données XML est bien entendu la créationde données sous ce format par un programme. Bien souvent, en effet, l’adoption d’untel format est la solution la plus élégante pour la présentation de données calculées.

Page 335: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Manipulation de données au format XML 343

Deux situations sont à envisager en fonction des données dont on dispose au dé-part. Si celles-ci sont obtenues à partir de données brutes (lexiques tabulés, fichierstexte, etc.), le code XML visé en sortie doit être construit de toute pièce. Si par contreles données initiales sont déjà au format XML, la problématique devient celle d’unetransformation du format initial. Ces deux cas de figure sontrésolus en suivant destechniques totalement différentes, qui sont détaillées ci-dessous.

9.3.1. Création de fichiers XML

S’il est tout à fait possible de produire des données XML en sortie d’un programmePerl en écrivant des chaînes correspondant à des balises (tout simplementvia la com-mandeprint ), il faut rappeler que cette opération nécessite un ensemble de précautionspour éviter de produire en sortie un document XML mal formé :

– l’entête du document doit être correct, et indiquer le codage des caractères ;

– le document doit être bien formé : toute balise ouverte doitêtre fermée, il ne peuty avoir de chevauchement entre balises, etc. ;

– les métacaractères (< > & " ’ ) contenus dans les parties textuelles doivent êtreremplacés par les entités XML correspondantes.

L’utilisation d’un module spécifique allège notablement l’écriture des balises etdes attributs, et vérifie la bonne formation du résultat. Le moduleXML::Writerpropose un ensemble de fonctionnalités de ce type.

Le programmeconversion-tag-XML.pl(listing 9.5) construit, pour un texte éti-queté par TreeTagger au format tabulé, un document XML. Il effectue de fait la trans-formation inverse de celle réalisée par le programmeanalyse-XML-simple.pl(lis-ting 9.1).

Listing 9.5 – conversion-tag-XML.plConversion d’un fichier de texte étiqueté en format XML

1 use locale;2 use strict;3 use XML::Writer;4

5 if ( $#ARGV != 0 ) 6 die "Usage : ", $0, " fichier_étiqueté\n";7 8

9 my $scripteur = new XML::Writer ( DATA_MODE=>1, DATA_INDEN T=>1 );10 $scripteur->xmlDecl( "iso-8859-1" );11 $scripteur->startTag( "texte", "source"=>$ARGV[0] );12

13 open (IN, "<", $ARGV[0]) or14 die "Problème ", $ARGV[0], " : ",$!,"\n";

Page 336: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

344 Perl pour les linguistes

15

16 my $num = 0;17 while ( my $ligne = <IN> )18 chomp $ligne;19 $num++;20 if ( not $scripteur->in_element( "phrase" ) )21 $scripteur->startTag( "phrase" );22 23 if ( $ligne =~ /(. * )\t(. * )\t(. * )/ )24 $scripteur->startTag( "mot", "num"=>$num );25 $scripteur->dataElement( "forme",$1 );26 $scripteur->dataElement( "lemme",$3 );27 $scripteur->dataElement( "categorie",$2 );28 $scripteur->endTag( "mot" );29

30 if ( $2 eq "SENT" )31 $scripteur->endTag( "phrase" );32 33 34 35

36 close (IN);37 if ( $scripteur->in_element( "phrase" ) )38 $scripteur->endTag( "phrase" );39 40

41 $scripteur->endTag( "texte" );42 $scripteur->end( );

Ligne de commande :perl conversion-tag-XML.pl fichier_étiqueté

Exemple :perl conversion-tag-XML.pl becass2.tag

oùbecass2.taga le contenu suivant :Le DET:ART le

vieux ADJ vieux

...

sa DET:POS son

province NOM province

. SENT .

Mais KON mais

...

Résultat (extrait) :

<?xml version="1.0" encoding="iso-8859-1"?><texte source="becass2.tag">

<phrase><mot num="1">

<forme>Le</forme>

Page 337: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Manipulation de données au format XML 345

<lemme>le</lemme><categorie>DET:ART</categorie>

</mot><mot num="2">

<forme>vieux</forme><lemme>vieux</lemme><categorie>ADJ</categorie>

</mot>...

<mot num="16"><forme>sa</forme><lemme>son</lemme><categorie>DET:POS</categorie>

</mot><mot num="17">

<forme>province</forme><lemme>province</lemme><categorie>NOM</categorie>

</mot><mot num="18">

<forme>.</forme><lemme>.</lemme><categorie>SENT</categorie>

</mot></phrase><phrase>

<mot num="19"><forme>Mais</forme><lemme>mais</lemme><categorie>KON</categorie>

</mot>...

</phrase>...

</texte>

REMARQUE.– La structure de ce document est détaillée en 9.2.1.

Détails du programme :

L’analyse du fichier contenant le texte étiqueté dont le nom est passé en argumentse fait de façon classique, en utilisant une expression régulière pour extraire de chaqueligne la forme, la catégorie et le lemme de chaque mot. Les différents éléments XMLsont ensuite écrits au fur et à mesure, en commençant par les éléments de plus hautniveau. Le marquage des phrases est réalisé au fur et à mesurede la lecture des motsdu texte suivant les principes suivants :

– à chaque nouveau mot, si aucune phrase n’est en cours, une nouvelle phrasecommence ;

– si l’on trouve un signe de ponctuation terminant une phrase(catégorieSENTproduite par TreeTagger) la phrase en cours se termine ;

Page 338: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

346 Perl pour les linguistes

– à la fin du texte, la dernière phrase est terminée si cela n’a pas déjà été fait (c’est-à-dire si le dernier item du texte n’est pas une ponctuation terminale).

Techniquement, l’utilisation du moduleXML::Writer passe par la créationd’un objet de ce type (que nous appelleronsscripteur), stocké dans la variable$scripteur . L’objet est créé avec deux paramètres qui permettent d’avoir en sor-tie un fichier XML « lisible ».DATA_MODEindique qu’il doit insérer des caractèresde fin de ligne après chaque balise fermante etDATA_INDENTque la profondeur dechaque élément doit être exprimée par une indentation (c’est-à-dire l’ajout d’espaceen début de ligne). Le code XML obtenu sans ces deux paramètres serait tout aussivalide, mais serait très peu lisible dans un éditeur de texte(il ne contiendrait ni espaceni caractères de fin de ligne).

Une fois créé, le scripteur peut recevoir les informations àproduire en sortie. Lesdifférentes méthodes disponibles sont :

– xmlDecl : génère la déclaration XML. Le seul paramètre pertinent iciest le co-dage des caractères utilisés, donciso-8859-1pour le codage par défaut de Perl (La-tin1). La ligne produite en sortie est la suivante :

<?xml version="1.0" encoding="iso-8859-1"?>

REMARQUE.– Cette déclaration n’entraîne pas le recodage automatique des chaînesde caractères si l’on déclare un autre codage queiso-8859-1. Si tel est le cas (parexemple si l’on désire utiliser le codageUTF-8 dans le document produit), il est né-cessaire de recoder explicitement les chaînes produites ensortie en utilisant le moduleEncode , décrit au paragraphe A2.5.5 (page 438) ;

– startTag : génère une balise ouvrante. Les paramètres de cette méthode sontle nom de la balise, suivie des couples (attribut, valeur) sil’élément correspondantpossède des attributs ;

– endTag : génère une balise fermante dont le nom est passé en paramètre ;

– dataElement: permet de générer un élément contenant du texte. Les paramètressont le nom de l’élément, son contenu textuel, et ses éventuels attributs. Le contenu dela chaîne passée en paramètre sera automatiquement converti en utilisant des entitésXML à la place d’éventuels métacaractères XML<, > ou &. Cette méthode effectueen fait trois opérations en une seule commande : l’insertiond’une balise ouvrante(avec ses attributs), d’un contenu textuel et d’une balise fermante. Son usage est bienentendu réservé aux éléments qui ne contiennent que du texte;

– end : déclare la fin du document XML. Cette opération entraîne unevérificationde la bonne formation du document produit ; des messages d’erreur sont affichés lecas échéant ;

– characters: n’est pas utilisée dans le programmeconversion-tag-XML.pl. Cetteméthode permet de produire un segment de texte (avec conversion des métacarac-tères). Elle est utile dans le cas où le texte n’apparaît pas dans un élément terminal

Page 339: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Manipulation de données au format XML 347

simple, comme c’est le cas pour l’annotation de texte ;

– emptyTag : n’est pas employée ici. Elle permet d’insérer une balise vide dont lenom et les attributs sont passés en paramètres.

Il est également possible d’interroger le scripteur afin d’obtenir des informationssur les éléments déjà produits. Ces interrogations se font par les méthodes suivantes :

– in_element : pour un nom d’élément donné en paramètre, renvoie une valeurbooléenne vraie si le dernier élément ouvert par le scripteur et non encore fermé estde ce type. Cette méthode est très utile dans notre exemple pour savoir si une phraseest en cours (ou s’il faut en commencer une nouvelle) ;

– current_element : non utilisée ici, cette méthode permet de connaître le nomdu dernier élément ouvert et non encore fermé. Les deux lignes de code suivantespermettant de savoir si une phrase est en cours ou non sont en fait équivalentes :

if ( $scripteur->in_element("phrase") ) ...

if ( $scripteur->current_element eq "phrase" ) ...

REMARQUE.– La sortie par défaut du scripteur est la sortie standard duprogramme.Pour qu’elle se fasse dans un fichier, il faut communiquer au scripteur (via le paramètreOUTPUT) une référence à un descripteur de fichier ouvert en écriture, de la façonsuivante :

open ( OUT, ">", "sortie.xml" ) or die "Pb ouverture\n";

my $scripteur = new XML::Writer

DATA_MODE => 1, DATA_INDENT =>1, OUTPUT => \* OUT;

9.3.2. Modification d’un fichier XML

Une autre situation courante d’utilisation des données en XML est celle où unprogramme va modifier un document XML. Cette situation peut bien entendu êtreramenée à celle d’une analyse et d’une écriture, en utilisant les méthodes vues précé-demment pour ces deux phases. Toutefois, il est également possible, en utilisant unereprésentation du document par un arbre, de modifier simplement cette représentationpar des méthodes spécifiques, et de produire en sortie le document XML correspon-dant.

Cette situation n’est bien sûr possible que dans les cas où lemoduleXML::DOMest utilisable, donc pour les documents XML relativement courts. L’avantage de cetteméthode est toutefois considérable : aucun des détails de l’écriture du document n’est àla charge du programmeur, et sa bonne formation du document est totalement garantie.

Le programmemodification-Ozkan.plréalise en une modification d’un documentdu corpus Ozkan détaillé en 9.1.2.1. Les modifications sont plus précisément :

Page 340: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

348 Perl pour les linguistes

– la suppression de tous les éléments de typekinesic_action ;

– l’ajout d’un élémentmodification_info dans l’entête du type :<head>

...

<modification_info>

<author>modification-Ozkan.pl</author>

<date>21-9-2006</date>

</modification_info>

...

Le nom du fichier XML est passé comme paramètre au programme, et le résultatde la modification est écrit en sortie standard.

Listing 9.6 – modification-Ozkan.plModification d’un document XML du corpus Ozkan : suppressiondes élémentskinesic_action et ajout de traces de la modification dans l’entête

1 use strict;2 use locale;3 use XML::DOM;4

5 if ( $#ARGV != 0 ) 6 die "Usage : ", $0, " fichier_xml\n";7 8

9 my $parseur = new XML::DOM::Parser;10 my $doc = $parseur->parsefile( $ARGV[0] );11

12 my $element_modification= $doc->createElement("modifi cation_info");13 my $element_auteur = $doc->createElement( "author" );14 my $texte_auteur = $doc->createTextNode( $0 );15 $element_auteur->appendChild( $texte_auteur );16 $element_modification->appendChild( $element_auteur ) ;17

18 my $element_date = $doc->createElement( "date" );19 my @tab_date = localtime;20 my $date = $tab_date[3]."-".( $tab_date[4]+1 )."-".21 ( $tab_date[5]+1900 );22 my $texte_date = $doc->createTextNode( $date );23 $element_date->appendChild ( $texte_date );24 $element_modification->appendChild( $element_date );25

26 my $entete = $doc->getElementsByTagName("head")->[0];27 $entete->appendChild( $element_modification );28

29 foreach my $element_kinesic (30 @$doc->getElementsByTagName("kinesic_action"))31 $element_kinesic->getParentNode->removeChild($eleme nt_kinesic);32 33

34 print $doc->toString;

Page 341: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Manipulation de données au format XML 349

Ligne de commande :perl modification-Ozkan.pl fichier_xml

Exemple :perl modification-Ozkan.pl C11ballon-ref-dial.xml

Résultat (extrait) :

<?xml version="1.0" encoding="UTF-8"?><dialogue xmlns:xsi="http://www.w3.org/1999/XMLSchem a-instance">

<head><coding_info>

<author>Julien Jacquot</author><date>00-03-11</date>

</coding_info><dialogue_info>

<couple instructor="Elise" manipulator="Daniel"strategy_manipulator="prudent">C11</couple>

<figure>ballon</figure></dialogue_info>

<modification_info><author>modifié par modifications- Ozkan.pl</author><date>21-9-2006</date></modification_info></head>

<body><verbal_action id="xsd:1" who="I">

<seg>qui est ce qui fait ça là</seg><comment type="speech_act">question introduite</comme nt>

</verbal_action>...

REMARQUE.– Les éléments ajoutés ne sont pas indentés ni séparés par des retours àla ligne. Le document XML produit est toutefois bien formé.

Détails du programme :

Le document XML est analysé exactement de la même façon que dansexpressions-Ozkan.pl(listing 9.4) dans les lignes 5 à 10.

Le programme se découpe ensuite en 4 étapes :

– les nouveaux éléments à ajouter dans l’entête sont créés, et leur contenu est cal-culé (auteur et date) : lignes 12 à 24 ;

– ces nouveaux éléments sont ensuite ajoutés à l’arbre (dansl’entête) : lignes 26 à27 ;

– les éléments de typekinesic_action sont supprimés de l’arbre : lignes 29à 32 ;

– l’arbre ainsi modifié est écrit sous la forme d’un document XML : ligne 34.

Page 342: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

350 Perl pour les linguistes

La création des éléments ajoutés dans l’entête se fait en commençant par l’élé-ment le plus haut dans l’arbre (élémentmodification_info ). Cette créationse fait en appliquant la méthodecreateElementqui s’applique à la racine du do-cument ($doc , produit par le parseur). Le nouvel élément ainsi créé (dansla va-riable$element_modification ) n’est pas encore un nœud de l’arbre. L’élémentauthor est ensuite créé de la même façon, ainsi que son contenu. Ce dernier est unélément de texte, et est créé par la méthodecreateTextNodeà laquelle est commu-niqué la chaîne qui constitue son contenu (ici, le nom du programme accessible dansla variable$0). Une fois ces différents composants créés, il convient ensuite de lesassembler. Pour cela, la méthodeappendChild permet d’ajouter un nouveau nœudfils à un nœud.

La même procédure est répétée pour la date de la modification.Pour obtenir ladate d’exécution du programme, la fonctionlocaltime de Perl fournit un tableau de9 valeurs correspondant aux informations suivantes (nous n’utiliserons que les troisqui sont signalées par un astérisque) : les secondes, les minutes, les heures, le jour dumois∗, le numéro du mois∗ (de 0 à 11), l’année∗ (depuis 1900), le jour de la semaine,le jour de l’année et une indication sur l’heure d’été. Pour deux d’entre elles, il estnécessaire d’effectuer un calcul supplémentaire, à savoirajouter 1 au numéro du moiset 1900 à l’année. Ainsi, le 21 septembre 2006 est indiqué au final par la chaîne21-09-2006.

Une fois l’élémentmodification_info construit et doté de ses éléments-fils,il convient de l’ajouter comme nouveau fils de l’entête (head ) du document. Le nœudhead est obtenu en utilisant la méthodegetElementsByNameprésentée en 9.2.3.Cette méthode renvoyant une référence à une liste de nœuds, il convient de préciserque l’on s’intéresse au premier (et unique) élément de cetteliste.

La suppression des élémentskinesic_action se fait à l’aide d’une boucle quiparcourt l’ensemble des nœuds correspondant à ces éléments. Pour chaque nœud àsupprimer, il suffit d’appliquer la méthoderemoveChild à son parent direct, en luicommuniquant l’identité du nœud à supprimer.

Une fois toutes les modifications effectuées, la productiondu document XML sefait tout simplement en utilisant la méthodetoString à la racine du document, cequi produit directement la chaîne de caractères correspondante qui n’a plus qu’à êtreaffichée.

Comme on le voit au travers de cet exemple, l’utilisation du moduleXML::DOMpour la modification reprend les mêmes principes que ceux vuspour l’analyse. Unensemble de méthodes permettent au final d’ajouter, de supprimer, et de modifier desnœuds de l’arbre. Le tableau 9.2 présente les principales méthodes de modification.

Il existe d’autres méthodes permettant notamment de modifier les nœuds ou deles déplacer, mais les méthodes ci-dessus permettent d’effectuer ces modifications par

Page 343: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Manipulation de données au format XML 351

étapes. Pour un usage intensif de cette approche, il est conseillé de se reporter à ladocumentation en ligne du moduleXML::DOM.

Méthode Descriptionélément = doc ->createElement Crée un nouvelélémentdans

le documentdoc.élément = doc ->createTextNode( contenu ) Crée un nouvel élément de

type texte dans le documentdoc, avec soncontenu.

père ->appendChild( fils ) Ajoute un nouveaufils aunœudpère. Le nouveau filsest placé à la suite des nœudsexistants.

père ->removeChild( fils ) Supprime le nœudfils quiétait préalablement un enfantdepère.

père ->insertBefore( fils , autre_fils ) Ajoute un nouveaufils aunœudpère. Le nouveau fils estplacé immédiatement avant lenœudautre_fils.

nœud->setAttribute( attribut => valeur ) Ajoute un nouvelattributà unélément et fixe savaleur (ouen modifie la valeur si l’attri-but existait déjà).

Tableau 9.2.Principales méthodes de modification deXML::DOM

9.4. Autres techniques et concepts

Les techniques présentées ici permettent de réaliser par unprogramme Perl la plu-part des exploitations envisageables de données XML et d’enproduire de nouvelles.Toutefois, de nombreux aspects des technologies XML n’ont pas été évoqués, car ilsnécessiteraient un ouvrage entier. Nous nous contenteronsde donner des pointeursvers les possibilités qu’offre le langage Perl pour quelques concepts liés à XML.

Pour une présentation plus complète des liens entre XML et Perl, voir l’ouvrage[RAY 02b] et l’excellent site duPerl XML Project6.

6. http://perl-xml.sourceforge.net/ .

Page 344: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

352 Perl pour les linguistes

9.4.1. Remarque sur le codage des caractères

Comme nous l’avons vu, le codage des caractères utilisé dansun document XMLest explicitement indiqué dans la première ligne du fichier.Les modules Perl chargésd’analyser les données disposent donc de l’information nécessaire pour une interpréta-tion correcte des caractères qui forment le document. Toutefois, pour harmoniser leurexploitation, ces modules vont systématiquement fournir àleur utilisateur les donnéesanalysées codées en Unicode (UTF-8), qui est le système de codage le plus étendu.Toutefois, rappelons qu’en Perl, lorsque de telles donnéessont affichées, elle subissentune transcodage versLatin1 lorsque cela est possible (c’est-à-dire si les caractères pré-sents dans les données sont tous compatibles avec ce jeu de caractères). Il n’est doncpas nécessaire de se préoccuper du codage des caractères tant que ceux-ci sont com-patibles avecLatin1, comme c’est le cas pour l’ensemble des données utilisées dansce chapitre.

Dans le cas contraire (si les données contenues dans le document sont, parexemple, dans une langue utilisant d’autres caractères), il est nécessaire d’adapter lecodage de sortie des programmes, par exemple en indiquant que la sortie doit se faireenUTF-8. Les instructions permettant d’effectuer cette adaptation sont présentées enannexe A2.

En ce qui concerne la production de données au format XML, il est par contre né-cessaire de produire des chaînes de caractères compatiblesavec le codage déclaré dansl’entête XML. Si ce codage n’est pasLatin1, il faut faire appel au moduleEncode(décrit au paragraphe A2.5.5 page 438) pour toutes les chaînes de caractères du docu-ment.

9.4.2. Modèles de documents et validation

La plupart des documents XML rencontrés font partie de collections, ou répondentà des normes particulières, comme les normes d’annotation de données linguistiquesque constituent la TEI ou CES.

Il est possible d’associer à chaque document XML une description du modèle au-quel il correspond, pour pouvoir vérifier la compatibilité de sa structure avec la normecorrespondante (on parle dans ce cas devalidité d’un document). Ces normes s’ex-priment par des formalismes du type DTD (Document Type Definition) ouXSD(XMLSchema Definition). Il est possiblevia un programme Perl de vérifier la conformitéd’un document à son modèle. Le moduleXML::Checker peut être utilisé pour réa-liser cette vérification.

Toutefois, dans la plupart des cas, le plus simple est d’utiliser un utilitaire spéci-fique, comme un éditeur XML permettant ce genre de vérification.

Page 345: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Manipulation de données au format XML 353

Le principe des normes de documents est présenté avec un bon aperçu des prin-cipes généraux de XML dans [RAY 02a].

9.4.3. Langages de requêtes en XML

Un des aspects les plus populaires des technologies XML est la possibilité de re-chercher des éléments dans un document en utilisant un langage de requête spécifique.Ces formalismes permettent d’exprimer des requêtes se basant sur la position d’un élé-ment dans la structure du document, mais aussi sur son contenu. La norme la plus ré-pandue estXPath, dont l’utilisation en Perl peut se fairevia le moduleXML::Xpath .

La normeXPathest également disponible par le moduleXML::LibXML , qui pro-pose une alternative au moduleXML::DOMavec des fonctionnalités supplémentaires.

9.4.4. Transformation de documents

La manipulation de documents XML a fréquemment pour but de transformer ceux-ci. Un document initial peut en effet donner lieu à la création (automatique) d’autresdocuments, que ce soit au format XML ou dans un autre format. Ces transformationspeuvent viser :

– l’attribution de caractéristiques physiques aux éléments en vue de produire undocument affichable ou imprimable (dans un format du type HTML, RTF, PDF, etc.) ;

– la sélection de certaines informations dans le document ;

– l’ajout de nouvelles informations.

Si ces transformations sont possibles par le biais d’une desapproches décritesdans ce chapitre, la technique dominante est l’utilisationdu langage de transformationXSLT. Ce langage, proche d’un langage de programmation, est spécifiquement dédiéà la sélection, l’ajout et la modification de parties de documents XML. S’il néces-site un apprentissage spécifique, son utilisation est toutefois possible localement dansun traitement par un programme Perl. Le moduleXML::XSLT permet d’automatiserl’application d’une transformation à un document.

Le langageXSLT, ainsi que la normeXPathqui y est intégrée sont décrits en détailsdans [DRI 02].

Page 346: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

354

Page 347: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

CHAPITRE 10

Exploitation linguistique du Web

10.1. Principes

De plus en plus de textes électroniques sont disponibles surle Web et des corpusentiers sont ainsi facilement téléchargeables, comme celaest présenté au chapitre 1.Toutefois, le Web lui-même est un corpus unique en son genre,dont la diversité etla taille en font un objet de choix pour l’étude du fonctionnement de la langue. Nousprésentons dans ce chapitre les techniques fondamentales permettant d’automatiser lerepérage, le téléchargement et le traitement de pages Web, qui permettent de consti-tuer un corpus en quelques heures. Nous aborderons également l’automatisation del’interrogation d’un moteur de recherche générique, dans le but par exemple d’obtenirrapidement des attestations et des contextes d’emploi d’unités lexicales ou d’expres-sions.

Avant d’aborder la présentation de ces techniques et des programmes associés, ilest toutefois nécessaire de préciser les principales notions concernant l’organisationdu Web et la nature des documents qui s’y trouvent.

10.1.1. Organisation du Web

Les documents présents sur le Web se répartissent en deux principaux types :

– des « pages Web », à savoir des documents complexes destinésà être visualiséspar un logiciel spécifique : un navigateur Web (les plus répandus étant Internet Explo-rer, Mozilla Firefox, Netscape, Safari, etc.) Ces documents sont disponibles au formatHTML1 ;

1. Il existe différentes versions de la norme HTML mais les distinctions entre celles-ci ne sontpas pertinentes pour le type d’exploitation considéré ici.

355

Page 348: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

356 Perl pour les linguistes

– des documents sous un format traditionnel, non spécifique àleur diffusion sur leWeb. On trouve ainsi des documents au format PDF, Doc, RTF, texte brut, etc.

Nous aborderons dans ce chapitre l’exploitation des documents de la premièrecatégorie.

10.1.1.1.Adresses URL

Tout document disponible sur le Web est identifié par une adresse, également ap-pelée URL2. Une URL typique est de la forme :

http://www.xxx.yyy/chemin/fichier.html

La séquence initialehttp fait référence au protocole réseau permettant d’accéderau document. Le protocole HTTP3 est le seul que nous considérons ici.

La séquencewww.xxx.yyy constitue l’adresse du serveur qui héberge le docu-ment en question. Il s’agit grossièrement d’un identifiant de la machine sur laquelleest stocké le document. Le préfixewww, bien que courant, n’est pas systématique. Ladernière partie de cette séquence permet d’identifier le type ou la localisation géo-graphique du serveur. Parmi les séquences (appelées domaines de premier niveau) ontrouve classiquementcom (pour les sites Web commerciaux),org (pour les organisa-tions),fr pour les sites hébergés en France, et ainsi de suite pour les autres pays (ukpour le Royaume-Uni,ca pour le Canada,be pour la Belgique,ch pour la Suisse,etc.).

La dernière partie d’une URL est le chemin d’accès au fichier contenant le docu-ment. Elle utilise le même principe que l’identification d’un fichier sur un systèmed’exploitation de type Unix (en utilisant la barre oblique/ comme séparateur), peutcomporter une suite de dossiers et de sous-dossiers, et finirpar le nom d’un fichierprécis.

Dans certains cas, l’adresse n’indique pas de nom de fichier.Elle identifie alorsun fichier dont le nom par défaut estindex.html ou une variante de ce nom(index.htm , default.html , etc.). L’URL http://www.cnrs.fr/ identifieen fait le fichierhttp://www.cnrs.fr/index.html .

Certaines URLs sont toutefois plus complexes, et prennent la forme d’une ligne decode du type :

http://www.google.fr/search?hl=fr&q=linguistique

2. Uniform Resource Locator.3. HyperText Transfer Protocol.

Page 349: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Exploitation linguistique du Web 357

Cette URL correspond à l’identification d’unepage dynamiquepar le standardCGI (Common Gateway Interface). A la différence d’une page classique, stockéedans un fichier sur le serveur Web, une page dynamique est créée par un programmeen fonction de paramètres qui sont généralement indiqués dans l’URL elle-même.Il s’agit ici d’une page de résultats du moteur de recherche Google. La partie ini-tiale identifie le serveur Web du moteurhttp://www.google.fr , tandis quela partie droite (search?hl=fr&q=linguistique ) indique les différents pa-ramètres nécessaires au moteur pour générer la page de résultats. Cette URL corres-pond à la réponse à une requête traitée par le moteur de recherche (via le programmesearch ) demandant des documents en français (hl=fr ) comportant le motlinguis-tique (q=linguistique ).

Hormis le fait que le document identifié par cette adresse estgénéré automatique-ment par le moteur, rien ne le différencie de ceux qui sontstatiques(c’est-à-dire dontle contenu est fixé à l’avance sur le serveur) lorsqu’il s’agit de le visualiser ou del’analyser.

10.1.1.2.Obtention d’adresses

On peut obtenir une adresse Web par de nombreux moyens (publicités, référencesdans un ouvrage, etc.). La connaissance de l’adresse est donc une information suffi-sante pour visualiser le document qu’elle identifie, et il suffit de saisir cette adressedans un logiciel de navigation.

Les autres sources naturelles de telles adresses sont bien entendu les pages Webelles-mêmes. La notion d’hypertexte implique justement lapossibilité d’associer plu-sieurs documents par le biais deliens. Un document HTML permet facilement de faireréférence à un autre document, en indiquant l’adresse de celui-ci dans son contenu. Unsite Web classique est ainsi constitué d’une collection de documents individuels reliésentre eux explicitement.

Une troisième source usuelle est l’utilisation d’un moteurde recherche. Ces ou-tils sont disponibles sur des sites Web largement connus (Google, Yahoo, MSN/LiveSearch, etc.) et permettent d’obtenir rapidement un grand nombre d’adresses par lebiais de mots-clés.

10.1.2. Structure générale d’une page HTML

HTML reste à l’heure actuelle le format standard pour organiser et présenter unepage Web. Un navigateur Web s’attend de toute façon à recevoir de tels documentspour les afficher (et fait appel à d’autres programmes dans les autres cas).

Le format HTML est avant tout un format texte (non binaire), au sein duquel l’en-semble du texte contenu dans le document est présent, agrémenté de séquences prédé-finies permettant d’indiquer la structure générale du document (titres, paragraphes), la

Page 350: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

358 Perl pour les linguistes

mise en forme souhaitée pour certains segments (gras, souligné, taille des caractères,etc.), les liens hypertextes, et l’insertion d’objets non textuels (images, tableaux, etc.).HTML fait partie de la même famille de langages qu’XML, mais est bien plus limitéque ce dernier. Il en reprend toutefois les mêmes principes,tels qu’ils sont décritsau chapitre 9. Nous ne détaillons pas ici l’analyse de la structure globale d’un docu-ment HTML, à la différence de ce qui est classiquement fait pour XML. La raisonprincipale est le manque d’homogénéité des documents trouvés sur le Web, qui exigepratiquement un traitement spécifique pour chaque document. Il est toutefois possibled’utiliser pour un document HTML les mêmes méthodes que pourun document XML,et notamment les modules d’analyseXML::Parser etXML::DOM.

La manipulation de documents au format HTML par les outils demanipulationde texte brut ne pose donc que peu de problèmes techniques. Les seules difficultésrésident généralement dans la gestion du codage des caractères et dans l’extractiondes seuls éléments de textes, c’est-à-dire l’élimination des instructions de mise enforme.

Un document simple au format HTML est présenté dans la figure 10.1 (page 359)tel qu’il est affiché par un navigateur. Ce document est un extrait de celui que l’ontrouve sur le site de l’ABU4 lorsque l’on demande à obtenir le texte desContes de laBécasseà l’URL suivante :

http://abu.cnam.fr/cgi-bin/donner?becass2

La figure 10.2 (page 359) présente le contenu du même documentHTML, mais telqu’il est obtenu par téléchargement avant d’être interprété et affiché par le navigateur.

L’ensemble du contenu textuel de ce court document est ainsivisible dans lecontenu du fichier HTML. Mais de nombreuses autres chaînes decaractères présentesdans le fichier n’apparaissent pas dans la version affichée. Ces chaînes sont pour laplupart comprises entre chevrons, comme<CENTER>ou<br> , et sont appeléesba-lises. Leur rôle est d’attribuer des statuts particuliers à certains éléments du texte ; parexemple<CENTER>indique que le segment de texte suivant doit être affiché au centrede la page. La balise</CENTER>marque la fin de la zone de texte concernée par cepositionnement. On trouve ainsi des balises indiquant que le texte doit être écrit engras, ou dans un style de titre, ou avec une taille de police supérieure, etc.

Les balises<br> correspondent à des retours à la ligne. En effet, la notion delignepour un document HTML doit être explicitement indiquée de cette façon : un simpleretour à la ligne dans un segment de texte n’a pas d’effet sur l’affichage. Ceci expliqueque le découpage général en lignes du document montré en exemple varie fortemententre les deux présentations.

4. Association des bibliophiles universels.

Page 351: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Exploitation linguistique du Web 359

ABU - COPIE becass2

TEXTES AUTEURS SOMMAIRE

Transfert du fichier becass2

Contes de la bécasse (1883)

Taille du fichier : 208 Ko

Avant toute copie, nous vous invitons à consulter la Licence ABU.Choisissez ensuite votre format de fichier :

HTML

Le texte est traduit au format HTML et donc lisible sur tous les types de machines. Notez bien qu'il ne s'agit pas d'une version hypertexte du fichier. Seules les balises de mise en forme sont utilisées.

...

Figure 10.1.Exemple de document au format HTML : présentation par unnavigateur

<html><head><meta content="text/html; charset=iso-8859-1"><title>ABU - COPIE becass2</title></head><body><CENTER><a href="http://abu.cnam.fr/BIB/index.html">TEXTES</ a><a href="http://abu.cnam.fr/BIB/auteurs">AUTEURS</a><a href="http://abu.cnam.fr/index.html">SOMMAIRE</a> <br></CENTER><br><H1 ALIGN=CENTER>Transfert du fichier becass2</H1><CENTER><FONT SIZE=+1>Contes de la b&eacute;casse (1883) </FONT><br><br><B>Taille du fichier : 208 Ko</B><br><br><p>Avant toute copie, nous vous invitons &agrave; consulter la<a href="donner_licence">Licence</a> ABU.<br>Choisissez ensuite votre format de fichier :</CENTER><p><a href="donner_html?becass2">HTML</a>&nbsp;&nbsp;</ p><P>Le texte est traduit au format HTML et donc <B>lisible surtous les types de machines</B>. Notez bien qu’il ne s’agit pa sd’une version hypertexte du fichier. Seules les balises de m iseen forme sont utilis&eacute;es. </P>...</body></html>

Figure 10.2.Exemple de document au format HTML : code source

Page 352: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

360 Perl pour les linguistes

Une balise particulière permet d’associer un lien hypertexte à un segment de texteau sein du document. Il s’agit de la balise<a ...> , qui comprend une séquence dutype href=" xxx " , la séquencexxx étant l’adresse du document visé par ce lien.Dans certains cas, l’adresse indiquée n’est pas aussi complète que celles habituelle-ment rencontrées : c’est le cas de la balise :

<a href="donner_html?becass2">

dont l’adresse ne commence pas par le classiquehttp:// et qui n’indique pas lenom du serveur. Il s’agit d’une adresse diterelative: les informations absentes peuventalors être déduites de l’adresse du document où se trouve le lien. Comme l’URL dudocument présenté ici est :

http://abu.cnam.fr/cgi-bin/donner?becass2

l’URL complète du lien ci-dessus est en fait :

http://abu.cnam.fr/cgi-bin/donner_html?becass2

Les autres éléments ayant un statut spécial sont les séquences comme&eacute;ou &agrave; . Elles correspondent respectivement aux lettres accentuées ‘é’ et ‘à’.Cette façon de représenter des caractères accentués est unepossibilité offerte par lelangage HTML, et permet d’éviter les problèmes de codage descaractères. De tellesséquences (prédéfinies dans la norme HTML) sont appeléesentités. Il existe des en-tités pour les lettres accentuées, mais aussi pour des caractères non standard commecertains symboles mathématiques ou graphiques : ainsi la séquence&nbsp; présentedans l’exemple identifie un espace insécable (no break space). Les problèmes de co-dage des caractères en HTML viennent du fait que le navigateur qui interprète le docu-ment ne connaît pas nécessairement la norme utilisée par le créateur du document. Lesentités sont une façon de les éviter, puisque tous les caractères problématiques (c’est-à-dire ceux ne faisant pas partie du code ASCII) sont ainsi « traduits » en séquencesde caractères standards (c’est-à-dire non liés à un choix decodage particulier). L’an-nexe A2 présente de façon détaillée les différentes façons de coder un texte.

Une description exhaustive du langage HTML, et notamment des balises et desentités est disponible sur le site du consortium W3C, responsable de la définition decette norme. Plus précisément :

– http://www.w3.org/TR/html4/index/elements.html pour lesbalises (également appelés éléments) ;

– http://www.w3.org/TR/html4/sgml/entities.html pour les en-tités.

10.1.3. Du HTML au texte brut

En résumé, le contenu d’un document au format HTML, bien que potentiellementcomplexe, est avant tout du texte qui reste manipulable facilement. Toutefois, certains

Page 353: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Exploitation linguistique du Web 361

éléments de ce texte peuvent poser quelques problèmes à un traitement automatique.C’est le cas des balises, des entités et également du codage des caractères.

Le principe que nous détaillerons ici est celui de la transformation d’un documentHTML en texte brut, c’est-à-dire en une version expurgée de toute chaîne relevant dela norme HTML.

Par exemple, le résultat de la transformation du document précédent aboutit autexte présenté en figure 10.3.

ABU - COPIE becass2TEXTES AUTEURS SOMMAIRETransfert du fichier becass2Contes de la bécasse (1883)Taille du fichier : 208 KoAvant toute copie, nous vous invitons à consulter la Licence ABU.Choisissez ensuite votre format de fichier :HTMLLe texte est traduit au format HTML et donc lisible sur tous le s typesde machines. Notez bien qu’il ne s’agit pas d’une version hyp ertexte dufichier. Seules les balises de mise en forme sont utilisées.

Figure 10.3.Texte obtenu à partir d’une page Web en HTML

Les transformations qui ont été réalisées sur le texte présenté en figure 10.2 sont :

– la suppression de toutes les balises (mise en forme, liens,etc.) ;

– le rétablissement des caractères accentués qui étaient représentés par des entités ;

– le positionnement des fins de lignes en respectant la logique des balises HTML.

10.1.4. Pages Web et codage des caractères

REMARQUE.– Cette section fait appel aux notions de codage des caractères présentéesplus en détails en annexe A2.

Le codage des caractères contenus dans une page Web relève dela seule décisionde son auteur. Pour un même texte en français, plusieurs possibilités de codage sonttout à fait envisageables sans que cela ne pose de véritablesproblèmes à un naviga-teur. Il n’en va pas de même pour une exploitation linguistique du contenu textuel dudocument.

Si le document n’utilise que des caractères appartenant au code ASCII, aucun pro-blème ne se pose, puisque ces caractères font partie de tous les systèmes de codage

Page 354: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

362 Perl pour les linguistes

connus (ces caractères servent à des opérations essentielles, comme l’écriture des ba-lises HTML). Lorsque le document contient des caractères accentués, les différentsjeux de codages disponibles peuvent toutefois être incompatibles.

Comme le système de codage d’une page ne peut pas être connu à l’avance, il estnécessaire de prendre un ensemble de précautions lorsque l’on souhaite traiter unepage Web quelconque.

Les recommandations liées à la conception d’une page Web en HTML offrent lapossibilité de préciser dans l’entête du document le système de codage utilisé (commec’est systématiquement le cas pour les documents XML). La déclaration se fait par lebiais d’une balise du type :

<meta http-equiv="content-type" content="text/html; ch arset= XX">

oùXX est le nom du codage utilisé, par exempleiso-8859-1 , UTF-8 , etc.

En l’absence d’une telle indication, les logiciels de navigation supposent généra-lement que le document est codé enLatin1 (ou iso-8859-1), suivant ainsi la normeHTML.

Rappelons que le problème du codage ne se pose pas si le document utilise systé-matiquement des entités pour représenter les caractères non standards.

10.1.5. Connexion à Internet

L’ensemble des programmes présentés ici nécessitent évidemment que la machinesur laquelle ils sont exécutés soit connectée à Internet. Letype de connexion importepeu (réseau d’un établissement, connexion privée par un fournisseur d’accès, etc.),mais certains environnements protégés peuvent nécessiterun réglage préalable.

Certaines configurations de réseau utilisent un serveur mandataire (ouproxy), au-trement dit un point de passage intermédiaire pour une connexion réseau. Ce dispositifpeut dans certains cas accélérer les connexions (par un système de cache). Il peut éga-lement servir de protection contre les intrusions extérieures (on parle également depare-feuou firewall) . Dans ce dernier cas, le passage par le serveur mandataire estobligatoire pour toute connexion, quel que soit l’application qui l’exploite (naviga-teur, client de messagerie, ou tout programme détaillé dansla suite de ce chapitre).

Si votre ordinateur est dans cette situation, votre administrateur réseau (ou four-nisseur d’accès) vous a communiqué les coordonnées de ce serveur. L’informationnécessaire à la configuration des applications est simplement le nom (ou l’adresse

Page 355: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Exploitation linguistique du Web 363

numérique) du serveur mandataire et un numéro de port. Par exemple, le serveur man-dataire peut être identifié par l’adresse : 172.1.1.1 et le port 1234. Ces deux informa-tions sont généralement présentées sous la forme d’une seule chaîne de caractères :172.1.1.1:1234 .

Pour tous les programmes Perl présentés par la suite, si l’utilisation d’un serveurmandataire est obligatoire pour un accès à internet, il est nécessaire d’ajouter la lignede code suivanteavant l’appel au(x) module(s) (par exempleuse LWP::Simplecomme présenté plus bas) permettant l’accès au réseau :

BEGIN $ENV"http_proxy" = "172.1.1.1:1234";

Bien entendu, l’adresse du serveur mandataire et son numérode port sont à rem-placer par celles qui correspondent à la configuration de votre connexion réseau.

Les listings présentés ci-après ne comportent pas cette instruction, qui devra êtresystématiquement ajoutée le cas échéant.

10.2. Récupération et nettoyage d’une page Web

Cette partie présente deux programmes Perl simples permettant d’automatiser letéléchargement d’une page Web se trouvant à une adresse (URL) donnée.

Le premier programme permet simplement de récupérer le codeHTML completde la page, alors que le second effectue en plus sa transformation en texte brut pourpermettre son exploitation en tant que donnée textuelle classique.

10.2.1. Récupération du code HTML d’une page Web

Etant donnée une URL, il est très simple en Perl d’automatiser la récupération ducode source (en HTML) de la page Web qui y correspond. Cette opération fait toute-fois appel à un module spécifique de Perl,LWPqui peut ne pas être installé par défaut.Le moduleLWPfait partie d’un ensemble de fonctionnalités concernant l’exploitationdu Web en Perl, baptisélib-www . Il est disponible pour toutes les distributions dePerl.

Nous n’utilisons ici qu’une partie de ce module, à savoir la version minimalisteidentifiée parLWP::Simple . Pour tous les programmes présentés ici il sera doncnécessaire de placer la ligne suivante dans l’entête du programme :

use LWP::Simple;

Page 356: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

364 Perl pour les linguistes

La principale fonctionnalité qu’offre ce module est la fonction get qui reçoit enparamètre une URL et renvoie dans une chaîne de caractères l’intégralité du contenude la page Web correspondante.

Le programmeURL-HTML.pl (listing 10.1) affiche en sortie standard, pour uneURL passée en argument, le contenu de la page Web correspondante.

Listing 10.1 – URL-HTML.plRécupération du code HTML complet d’une page Web

1 use strict;2 use locale;3 use LWP::Simple;4

5 if ( $#ARGV != 0 ) 6 die "Usage : ", $0, " URL\n";7 8

9 my $URL = $ARGV[0];10 my $page = get( $URL );11

12 if ( not defined( $page ) )13 die "Problème lors du téléchargement !\n";14 15

16 print $page,"\n";

Ligne de commande :perl URL-HTML.pl URL

Exemple :perl URL-HTML.pl "http://abu.cnam.fr/cgi-bin/donner?b ecass2"

Résultat : voir figure 10.2.

REMARQUE.– Les guillemets doubles (" ) autour de l’URL donnée en exemple serventà empêcher le système d’exploitation d’interpréter le caractère? comme un joker dansla syntaxe de la ligne de commande. Ces guillemets ne sont toutefois pas transmis auprogramme, et ce dernier n’a pas à les prendre en charge.

Détails du programme :

Etant donnée la chaîne contenant l’URL passée en paramètre,la principale actionde ce programme est effectuée par la fonctionget. La valeur retournée pargetest unechaîne de caractères correspondant à l’ensemble du code HTML de la page correspon-dante, à condition qu’aucun problème ne soit intervenu pendant le téléchargement.

Page 357: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Exploitation linguistique du Web 365

Cette chaîne est donc susceptible d’être très longue et de contenir plusieurs lignesde texte. A la différence des fichiers de texte lus directement depuis le système d’ex-ploitation, la notion de ligne n’est pas prise en compte ici :le protocole HTTP qui gèrele téléchargement de la page effectue le transfert des données en un seul bloc. Lors del’exploitation de ces données, il est donc nécessaire de prendre en compte la présencede caractères de fin de ligne dans le contenu du document.

Si un incident s’est produit, et que le contenu de la page n’a pas été correctementrécupéré par la fonctionget. Dans ce cas, la valeur de retour de la fonction (stockéedans$page ) est indéfinie. Le programme se contente alors d’afficher un messaged’erreur via la commandedie. Les problèmes rencontrés à ce stade peuvent avoirdifférentes origines :

– le document correspondant à l’URL n’existe pas (l’URL est mal saisie, le serveurWeb a modifié son contenu, etc.) ;

– l’accès réseau au serveur Web n’est pas possible (encombrement du réseau, ser-veur en panne, etc.) ;

– la machine sur laquelle le programme est exécuté a des problèmes d’accès auréseau.

Dans les trois cas la réponse du programme est la même. Un navigateur Web,quant à lui, a accès à différentes informations pour identifier la nature de l’erreur enaffichant un message spécifique. Le moduleLWP::Simple ne permet pas d’obtenircette information. Pour mieux contrôler ce mécanisme, il est nécessaire de faire appelà d’autres modules Perl plus complexes (commeLWP::UserAgent ).

10.2.2. Récupération du contenu textuel d’une page Web

Le programmeURL-HTML.pl (listing 10.1) se contente d’afficher en sortiele contenu brut de la page Web demandée. Nous allons maintenant présenter undeuxième programme permettant automatiser l’extraction du seul texte contenu dansla page, afin d’obtenir par ce biais des données exploitablesdirectement.

Comme nous l’avons vu plus haut, les problèmes à traiter sontles suivants :

– normalisation du codage des caractères ;

– élimination des balises et des segments de code correspondant à des programmesintégrés à la page ;

– remplacement des entités HTML.

Le programmeURL-texte.pl (listing 10.2) fonctionne sur le même principequeURL-HTML.pl (listing 10.1), mais affiche en sortie standard le contenu textuelde la page Web dont l’URL lui est passée en argument.

Page 358: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

366 Perl pour les linguistes

Listing 10.2 – URL-texte.plRécupération d’une page Web et transformation en texte brut

1 use strict;2 use locale;3 use LWP::Simple;4 use Encode;5 use HTML::Entities;6

7 if ($#ARGV != 0) 8 die "Usage : ", $0, " URL\n";9

10

11 my $URL = $ARGV[0];12 my $page = get( $URL );13

14 if ( not defined($page) )15 die "Problème lors du téléchargement !\n";16 17

18 my $codage_page = "latin1";19 if ($page =~ /\bcharset\s * =\s * ([\w-]+)/i) 20 $codage_page = $1;21 eval decode ($codage_page, "test") ;22 if ( defined ($@) ) 23 $codage_page = "latin1";24 25 26

27 my $page_unicode = decode( $codage_page, $page );28 my $texte_unicode = supprime_html( $page_unicode );29 my $texte = normalise_latin1( $texte_unicode );30

31 print $texte,"\n";32

33 sub supprime_html 34

35 my @balises_a_ignorer =36 ("applet","code","embed","head","object","script"," server");37

38 my $html = shift @_;39 $html =~ s/\n+/ /g;40 $html =~ s/\r+/ /g;41

42 decode_entities($html);43

44 foreach my $balise (@balises_a_ignorer) 45 $html=~s/<$balise. * ?<\/$balise>//ig;46 47

48 $html =~ s/<!--. * ?-->//g; #commentaires49 $html =~ s/<\/?p\/?>/\n/ig; #paragraphes50 $html =~ s/<br\/?>/\n/ig; #retours à la ligne51 $html =~ s/<\/tr>/\n/ig; #lignes de tableau52 $html =~ s/<\/?h[1-6]>/\n/ig; #titres53 $html =~ s/<\/?div. * ?>/\n/ig; #sections54

55 $html =~ s/<. * ?>//g; #autres balises56 $html =~ s/\s * \n\s * /\n/g; #espaces en début/fin de ligne57 $html =~ s/ +/ /g; #séquences de plusieurs espaces58

Page 359: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Exploitation linguistique du Web 367

59 return $html;60 61

62 sub normalise_latin1 63 my $chaine = shift @_;64 $chaine =~ s/[\x2019\x2018]/\’/g;65 $chaine =~ s/[\x201C\x201D]/\"/g;66 $chaine =~ s/[\x2013\x2014]/-/g;67 $chaine =~ s/\x2026/.../g;68 $chaine =~ s/\x0152/OE/g;69 $chaine =~ s/\x0153/oe/g;70 $chaine =~ s/[^\x0000-\x00FF]//g;71 return $chaine;72

Ligne de commande :perl URL-texte.pl URL

Exemple :perl URL-texte.pl "http://abu.cnam.fr/cgi-bin/donner? becass2"

Résultat : voir figure 10.3.

Détails du programme :

La téléchargement du code HTML de la page dont l’URL est passée en paramètrese fait de la même façon que dansURL-HTML.pl, et son contenu est stocké dans lavariable$page .

La première étape du traitement concerne la prise en compte du codage des ca-ractères de la page. Comme nous l’avons dit plus haut, il existe plusieurs codagespossibles mais l’information est généralement disponibledans le code de la page elle-même, dans une séquence de l’entête du type :charset= XXX. Pour traiter correcte-ment la page, il est nécessaire de recoder le contenu de celle-ci dans le codage internede Perl (Unicode), à partir du codage utilisé. Ce codage est obtenu par projection d’uneexpression régulière. Si cette projection échoue, le programme considère (peut-être àtort) que le codage utilisé estLatin1, ce qui est toutefois la recommandation de lanorme HTML.

La deuxième étape concerne l’extraction du contenu textuelde la page, en sup-primant les balises et les éventuels éléments indésirables, et en traduisant les entitésHTML. L’extraction du texte est réalisée par la fonctionsupprime_html qui estdétaillée ci-dessous.

Dans une dernière étape, le texte est normalisé afin de garantir un affichage correcten codageLatin1puis est affiché en sortie standard.

Page 360: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

368 Perl pour les linguistes

En résumé le contenu de la page est disponible au cours du traitement dans lesvariables suivantes :

– $page contient le code HTML complet de la page, dans son codage d’origine ;

– $page_unicode a le même contenu, mais dans le format Unicode interne dePerl ;

– $texte_unicode contient le texte de la page ;

– $texte contient le texte normalisé enLatin1destiné à être affiché.

Le passage d’un système de codage à l’autre est réalisé en utilisant le moduleEncode , et plus précisément la fonctiondecode. Cette fonction permet de passerd’un codage quelconque au codage interne de Perl. Toutefois, si la chaîne de caractèressituée aprèscharset= ne correspond pas à un véritable codage, la fonctiondecodeva échouer et entraîner un arrêt du programme. Avant de l’exécuter pour analyserla page, il est donc nécessaire de s’assurer que ce n’est pas le cas. Cette vérificationutilise la fonctioneval, qui permet d’exécuter un bloc d’instructions Perl en récupérantles éventuelles erreurs dans la variable spéciale$@(voir paragraphe 5.2.3 page 196).C’est ce qui est fait en lignes 21 à 24, en appliquant le codageindiqué dans la pagesur la chaîne"test" . Si une erreur se produit à ce stade, on supposera que le codageest en réalité celui par défaut, à savoirLatin1. L’instruction de la ligne 27 va ainsi sedérouler sans risquer d’interrompre le programme.

La fonctionsupprime_html reçoit en entrée le code HTML de la page analy-sée, et renvoie son seul contenu textuel. Les opérations qu’elle applique à l’ensemblede la page sont les suivantes :

1) remplacement des fins de lignes et retours-chariots par des espaces (lignes 39et 40). Comme le langage HTML n’accorde aucune significationparticulière à la no-tion de ligne, ces caractères n’ont généralement aucune pertinence pour l’organisationinterne du document ;

2) décodage des entités HTML (ligne 42). Cette opération permet par exemplede remplacer les séquences du type&eacute; par le caractère correspondant (é).Elle est effectuée par la fonctiondecode_entitiesdu moduleHTML::Entitiesqui est invoqué en début de programme. Ce module fait partie de la bibliothèquelibwww-perl , et est donc installé en même temps que les autres modules Perl per-mettant d’exploiter le Web ;

3) suppression des segments de code HTML non textuels (lignes 44 à 46). Cetteétape concerne essentiellement les entêtes de document HTML et les parties de codesinformatiques pour les pages complexes. Ils sont délimitéspar une des sept balises dela liste@balises_a_supprimer . Tout segment du code source de la page encadrépar une de ces balises est simplement supprimé ;

4) suppression des commentaires (ligne 48). Comme dans n’importe quel langageinformatique, il est possible d’insérer du texte en commentaire, qui n’est pas pris en

Page 361: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Exploitation linguistique du Web 369

compte lors de l’utilisation du code (par exemple lors de l’affichage de la page par unnavigateur). En HTML, les commentaires se trouvent entre les chaînes<!-- et --> ;

5) remplacement des balises de séparation des blocs de textes par des fins de lignes(lignes 49 à 53). Certaines balises ont une signification précises dans le formatagedu document. Les balises<p>, </p> et <p/> indiquent des paragraphes,<br> et<br/> des fins de lignes,<tr> et </tr> des fins de lignes dans un tableau, et lesbalises<h1> à<h6> et<div> des titres et des sections d’un texte. Le sens de toutesces balises est donc celui d’une séparation entre le texte qui les précède et celui quiles suit. Ceci se traduit en sortie par des fins de ligne explicites dans le texte extrait ;

6) suppression de toutes les balises restantes (ligne 51) etnormalisation des es-paces (lignes 56 et 57). La normalisation des espaces évite notamment d’avoir desespaces en début et fin de ligne, ainsi que des séquences de plus d’un espace.

La fonctionnormalise_latin1 permet de produire un texte qui s’affiche cor-rectement en utilisant le codageLatin1, en transformant ou supprimant les caractèreséventuels de la page qui ne font pas partie de ce jeu de caractères (essentiellement ceuxqui proviennent des codages spécifiques à Windows, comme lesligatures, et certainssignes de ponctuation). Le détail de son fonctionnement estprésenté en annexe A2(paragraphe A2.6.3 page 439).

Si toutefois la sortie finale du programme devait être enUTF-8, deux modificationsseraient nécessaires :

– indiquer que le codage de la sortie standard doit êtreUTF-8, via l’instructionsuivante en début de programme :

binmode ( STDOUT, ":encoding(utf8)" );

– supprimer l’appel à la fonctionnormalise_latin1 .

10.2.3. Récupération récursive d’un site Web

Les programmes présentés précédemment se contentent de traiter une seule URL àla fois. Il est bien entendu possible de les modifier de telle façon qu’ils puissent effec-tuer le téléchargement et le traitement de listes d’URL. Il est également envisageablede les adapter afin d’extraire d’une page analysée la liste des liens qui s’y trouvent.Cette technique est celle utilisée par certains programmesde parcours systématiquedu Web, appelésrobots(web spiders, ou encorecrawlers). Leur principe est le sui-vant : à partir d’une adresse, ces programmes téléchargent la page correspondante eten extraient les liens hypertextes. Puis, pour chaque adresse ainsi obtenue, ils répètentl’opération, jusqu’à épuisement des liens disponibles.

Ce type de programme pose plusieurs problèmes, tant d’un point de vue techniqueque du point de vue des nuisances qu’ils sont capables d’engendrer.

Page 362: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

370 Perl pour les linguistes

Les problèmes techniques sont liés à l’identification de liens (qui peuvent s’expri-mer de différentes façons), mais aussi au danger de voir le programme revenir sur sespas (si deux pages ont des liens l’une vers l’autre, une boucle infinie peut se mettre enplace).

Les problèmes de comportement sont liés au trafic réseau engendré par de tels pro-grammes. Alors qu’une page Web est à l’origine prévue pour être lue par un humain(qui va prendre le temps de la lire, et n’en lira que quelques-unes dans une période detemps donnée), un tel programme est capable de télécharger et de traiter rapidementun très grand nombre de documents, et de saturer ainsi les capacités du serveur qui lesmet à disposition. Afin de limiter ces nuisances, un certain nombre de garde-fous ontété mis en place sur le Web, qui prennent la forme de règles de bonne conduite que lesauteurs de tels programmes sont invités à respecter.

Nous ne développons pas ici le détail des techniques à mettreen place pour créerun tel programme, ni pour s’assurer qu’il exploite correctement les ressources du Web.Les lecteurs intéressés peuvent trouver les moyens techniques de mettre en place untel programme en Perl dans le moduleLWP::RobotAgent . Les règles de bonneconduite sont disponibles sur les sites suivants :

– http://www.robotstxt.org/ ;

– http://www.searchtools.com/robots/ .

10.3. Interrogation d’un moteur de recherche

AVERTISSEMENT.– Comme c’est le cas pour l’utilisation de technologies récentesen Perl, les manipulations présentées dans la suite de ce chapitre font appel à destechniques complexes et utilisent des modules développés pour des traitements spéci-fiques. Les implications en sont que les éléments du langage Perl couverts jusqu’icine suffisent plus à décrire complètement la syntaxe utilisée. Les exemples de pro-grammes présentés sont clairement commentés et peuvent aisément servir de base àde nouveaux traitements, en recyclant les éléments de code les plus complexes sansles modifier. Plus précisément, les aspects de Perl impliqués ici sont la programmationobjet et la manipulation de structures de données par références. Une présentation deces principes est disponible en annexe A4.

Les moteurs de recherche sur le Web sont des services largement utilisés pourtrouver rapidement des documents. Leur utilisation passe normalement par l’accès àune page d’accueil spécifique, qui permet à l’utilisateur dedonner un ou plusieursmots-clés et de recevoir en réponse une liste de liens vers des documents en rapportavec ces mots-clés.

L’utilisation du Web à des fins de recherche linguistiquevia les moteurs de re-cherche a de nombreuses facettes, parmi lesquelles :

Page 363: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Exploitation linguistique du Web 371

– l’obtention de contextes d’utilisation d’un mot ou d’une expression ;

– le calcul de fréquences d’emploi ;

– la constitution de corpus homogènes autour d’un thème donné.

Dans tous ces cas, il est souhaitable d’automatiser la collecte des données, puis-qu’il est nécessaire soit d’interroger le moteur avec de nombreuses requêtes, soit detraiter un à un les documents dont les adresses constituent la réponse du moteur.

L’interrogation automatique d’un moteur de recherche poseles mêmes problèmesde comportement que les programmes de parcours systématique du Web : ils sollicitentde façon anormalement importante (par rapport à un utilisateur humain) les capacitésde traitement des moteurs. De ce fait, les principaux moteurs disponibles à l’heureactuelle ont mis en place des systèmes de protection empêchant leur interrogation pardes moyens automatiques sans leur permission.

Conscients des besoins de certains utilisateurs, certainsmoteurs proposent uneprocédure spécifique permettant leur interrogation par un programme informatique,mais avec un ensemble de restrictions, notamment en termes de nombre de re-quêtes en un temps donné. Nous détaillons les services proposés par deux des prin-cipaux moteurs qui proposent des services de ce type. Il s’agit des moteursYahoo(http://search.yahoo.com ) etLive Search(http://www.live.com , réa-lisé par la société Microsoft, qui a récemment remplacé leurmoteurMSN).

REMARQUE.– Les programmes présentés dans la suite de ce chapitre sonttotalementdépendants des services proposés par les moteurs de recherche. La rapide évolutiondes technologies utilisées et des conditions d’utilisation peut donc entraîner l’arrêt dufonctionnement d’un ou plusieurs de ces programmes et ce, indépendamment de notrevolonté5.

Les programmes présentés ici correspondent à une utilisation opérationnelle aumoment de la sortie de cet ouvrage. En cas de modifications importantes, des mises àjour seront proposées sur le site Web d’accompagnement de l’ouvrage6.

Enfin, il est tout à fait possible que de nouveaux moteurs de recherche développentde telles possibilités : dans ce cas les technologies présentées ici pourront leur êtreadaptées.

5. A titre d’exemple, le moteur Google (www.google.com ) a suspendu en 2006 les possibi-lités d’abonnement à ce type de service.6. http://perl.linguistes.free.fr/ .

Page 364: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

372 Perl pour les linguistes

10.3.1. Syntaxe des requêtes

L’automatisation de l’interrogation des moteurs de recherche utilise les mêmesprincipes que leur utilisation « manuelle »via un navigateur. Nous détaillons ici ledétail de la syntaxe des requêtes soumises à ces moteurs.

Syntaxe de base

Une requête élémentaire est formée d’un mot simple (c’est-à-dire sans espaces nitirets). Dans ce cas, le moteur renverra comme réponse une liste de liens vers des pagescontenant ce mot.

Si la requête est formée de deux ou plusieurs mots séparés pardes espaces, lemoteur considère qu’il s’agit d’une conjonction, autrement dit que l’utilisateur désiretrouver des documents contenant tous ces mots, sans contraintes sur leur ordre ou leurposition relative. Par exemple, la requête :

cheval course

est susceptible de ramener des documents contenantcheval de course, mais aussicourse de cheval, ainsi que des documents qui contiennent ces deux termes dans desphrases ou des parties totalement distinctes.

Si l’on souhaite au contraire indiquer que l’on cherche des documents contenantl’un des mots indiqués (disjonction), il faut placer le connecteur logiqueORentre lestermes. Ainsi la requête :

cheval OR course

est susceptible de ramener des documents contenant uniquementchevalou unique-mentcourseou les deux.

Le connecteur logiqueANDpeut aussi être utilisé explicitement. De même il estpossible de combiner plusieurs connecteurs en utilisant des parenthèses comme dansune expression logique en Perl. Par exemple :

cheval AND (course OR viande)

ramène des documents contenant nécessairementcheval, ainsi qu’un des deux motscourseouviande.

Le langage de description des requêtes contient également l’opérateur de négationNOTqui permet d’exclure des résultats les documents contenantun mot donné. Parexemple :

cheval NOT viande

Page 365: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Exploitation linguistique du Web 373

correspond aux documents contenant le motchevalmais pas le motviande. Une nota-tion alternative est de placer le caractère- (signe moins) devant le terme à exclure :

cheval -viande

est équivalente à la requête précédente.

Si l’on souhaite utiliser une expression comme terme de recherche, il faut la pla-cer entre guillemets, pour que les mots qui la composent ne soient pas interprétéscomme étant en simple conjonction. Ainsi, pour rechercher des documents contenantl’expressioncheval de course, il faut utiliser la requête suivante :

"cheval de course"

Contraintes sur les documents

Les moteurs offrent la possibilité d’exprimer dans les requêtes des contraintessur les documents recherchés. Ces contraintes peuvent porter sur le format des do-cuments, le nom des serveurs les hébergeant, ou encore leur date de création. Lescontraintes disponibles, de même que les syntaxes correspondantes varient d’un mo-teur à l’autre, il est donc nécessaire de se reporter aux indications fournies sur lessites Web (on trouve généralement un lien depuis la page d’accueil vers différentesrubriques d’aide).

10.3.2. Remarques sur les résultats des moteurs

La masse des documents indexés par les moteurs, et le grand nombre d’utilisa-teurs ont conduit les concepteurs à développer des traitements pouvant poser des pro-blèmes pour une utilisation linguistique. Les principaux traitements connus ayant uneinfluence sur les résultats sont :

– la lemmatisation : la plupart des moteurs effectuent un traitement minimal dela flexion au moment de l’indexation des documents. Il est fréquent de retrouver enréponse à une requête des documents comportant le terme recherché sous une autreflexion ;

– la suppression des accents : certains moteurs ne tiennent pas compte des lettresaccentuées lorsqu’ils indexent les pages Web, et les remplacent le cas échéant par lalettre de base : de ce fait, deux termes ne se différenciant que par des accents (commepeche, pêchéet péché) donneront les mêmes résultats ;

– la suppression des « mots vides » : pour minimiser la taille de l’index certainsmots courants (déterminants, prépositions, etc.) en sont exclus et ne peuvent être uti-lisés directement comme termes de la requête ;

Page 366: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

374 Perl pour les linguistes

– la limitation de la taille des requêtes : bien qu’il soit possible de concevoir desrequêtes très longues (comportant plusieurs dizaines de termes), celles-ci sont généra-lement tronquées (la limite pouvant varier de 80 à 250 caractères suivant les moteurs) ;

– une mauvaise interprétation des requêtes logiques : les connecteurs logiques(AND, ORet NOT) sont prévus par les concepteurs pour un usage minimal. Des re-quêtes y faisant massivement appel (dans la limite de la taille maximale indiquée pré-cédemment) peuvent être interprétées de façon erronée.

Dans certains des cas, les trois premières limites peuvent être contournées en pla-çant systématiquement les termes de la requête (même si ellen’en contient qu’un seul)entre guillemets, et/ou précédés d’un signe+.

Enfin, l’ordre dans lequel les moteurs de recherche présentent les documents n’estpas toujours facile à interpréter. Différentes stratégiessont mises en œuvre, dont lesparamètres sont les suivants (les concepteurs des moteurs ne divulguant pas le détailde la procédure de classement) :

– le nombre d’occurrences des termes de la requête dans le document ;

– la position des termes : une occurrence dans le titre ou en début de document estpréférée ;

– la notoriété des documents : un document vers lequel pointent de nombreux lienshypertextes sera favorisé ;

– l’achat de mots-clés par des sociétés commerciales qui souhaitent voir leur siteplacé en début de liste pour un ensemble de termes. Ces sites sont généralement indi-qués à part dans la liste des documents.

Il ne faut donc en aucun cas espérer que la pertinence des résultats fournis soitbasée sur des critères plus fins ou liés à des considérations linguistiques. L’ensemblede ces considérations limite bien entendu l’utilisation des moteurs de recherche à desfins d’investigation linguistique, mais leur facilité d’accès et la masse de données dis-ponible contrebalance ces inconvénients.

10.3.3. Interrogation automatique de Yahoo :Yahoo Web Search Services

Yahoo7 est un moteur de recherche généraliste qui propose un accès automatiqueen plus d’une interrogation manuelle par un navigateur. Plus précisément, il est pos-sible, par le biais de ce service, d’automatiser l’envoi de requêtes au moteur de re-cherche, et d’obtenir en réponse le nombre de pages Web correspondantes, leursadresses et leurs descriptions.

7. http://search.yahoo.com .

Page 367: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Exploitation linguistique du Web 375

10.3.3.1.Inscription et installation

Le système d’interrogation automatique de Yahoo demande une inscription gra-tuite préalable. Cette inscription consiste en la créationd’un identifiant d’applicationqui devra par la suite être communiqué avec chaque requête. La déclaration de cetidentifiant se fait sur le formulaire en ligne situé à l’adresse suivante (il vous sera aupréalable demandé de créer un compte personnel sur les services Yahoo) :

http://api.search.yahoo.com/webservices/register_ap plication

Le nombre de requêtes autorisées par jour est limité. Cette limite peut varier, maisse situe généralement autour de quelques milliers par tranche de 24 heures. La limitese base sur l’adresse internet de l’ordinateur qui émet les requêtes, indépendammentde l’identifiant utilisé.

Les conditions d’utilisation et les détails techniques sont accessibles sur le site :

http://developer.yahoo.com/

Du point de vue technique, la communication avec le moteur deYahoo se faitviaune URL qui contient les différents paramètres de la requête. Cette URL est complexe ;le moduleURI::URL , qui fait partie de la bibliothèquelib-www , permet de facili-ter sa construction. Cette URL est ensuite utilisée de façonclassique en faisant appelau moduleLWP::Simple . Cependant, la réponse est renvoyée par le moteur sous laforme d’un document XML, et doit donc être analysée en utilisant les techniques pré-sentées au chapitre 9. L’analyse de ces documents XML est très facile car leur structureest très simple. Il est notamment possible d’utiliser le module XML::Simple , dontle résultat est une structure de données Perl classique. Pour plus de détails sur ce point,voir paragraphe 9.2.1 (page 328).

10.3.3.2.Exemple de programme : obtention de la liste des titres, URLset descrip-tions de documents pour une requête

Le programme Perl présenté ici fonctionne de la façon suivante : pour une requête(chaîne de caractères) donnée en argument, il affiche en réponse le nombre de docu-ments correspondants dans l’index de Yahoo, et pour les 20 premiers documents leuradresse, titre, et description.

Listing 10.3 – recherche-Yahoo.plInterrogation de Yahoovia Yahoo Web Search Services

1 use locale;2 use strict;3 use Encode;4 use URI::URL;5 use LWP::Simple;6 use XML::Simple;7

8 if ( $#ARGV != 0 )9 die "Usage : ", $0, " requete\n";

Page 368: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

376 Perl pour les linguistes

10

11 my $requete = encode("utf8", $ARGV[0]);12

13 # NOTE : insérez ci-dessous l’identifiant que vous avez décl aré14 # auprès de Yahoo Web Search Services lors de votre inscripti on.15 # Reportez-vous au site http://developper.yahoo.com/16

17 my $identifiant_Yahoo = "xxx";18

19 my $url_yahoo = url(20 "http://api.search.yahoo.com/WebSearchService/V1/we bSearch");21

22 $url_yahoo -> query_form (23 appid => $identifiant_Yahoo, #identifiant24 query => $requete, #requête25 region => "fr", #serveur Yahoo26 type => "phrase", #type de requête27 results => 20, #nombre de documents (max 100)28 start => 1, #numéro du premier document29 format => "html", #format des documents30 adult_ok => 1, #contrôle parental31 similar_ok=> 0, #maintien des docs similaires32 language => "fr", #limitation à une langue33 country => "fr", #limitation à une zone34 output => "xml" #format de la réponse35 );36

37 my $reponse_yahoo = get( $url_yahoo );38

39 if ( defined( $reponse_yahoo ) )40 my $arbre_XML = XMLin($reponse_yahoo, ForceArray =>["Res ult"]);41 my $nb_docs = $arbre_XML -> "totalResultsAvailable";42 print "TOTAL : ", $nb_docs,"\n";43 if ( defined ( $arbre_XML->"Result" ) ) 44 my @resultats = @$arbre_XML->"Result";45 foreach my $document (@resultats)46 print "---\n";47 my $titre = normalise_latin1( $document->"Title" );48 print "TITRE : ", $titre, "\n";49 my $URL = $document->"Url";50 print "URL : ",$URL,"\n";51 my $desc = normalise_latin1( $document->"Summary" );52 print "DESCRIPTION : ",$desc,"\n";53 54 55 56 else 57 die "Problème de la part de Yahoo !\n";58 59

60 sub normalise_latin1 61 ...62

Ligne de commande :perl recherche-Yahoo.pl requête

Exemple 1 :perl recherche-Yahoo.pl cheval

Page 369: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Exploitation linguistique du Web 377

Exemple 2 :perl recherche-Yahoo.pl "\"cheval de\""

Résultat (exemple 2) :TOTAL : 1020000---TITRE : Cheval de Troie - WikipédiaURL : http://fr.wikipedia.org/wiki/Cheval_de_TroieDESCRIPTION : ... Vos dons permettent à Wikipédia de continu er à exister !Merci de votre soutien. Cheval de Troie ... légendaire, on a c réé leterme "Cheval de Troie" pour parler d’un don se ...---TITRE : Randonnée à cheval voyage équestre stage équitation randonnéesgite week-end voyage à cheval séjour équestre...URL : http://www.1cheval.com/DESCRIPTION : ... de concours complet, un premier critérium européen du jeunecheval de complet, et la fête de l’Anglo-Arabe sur le ...---TITRE : Cheval Annuaire cheval annonces salon photo vente ch eval equitationcheval equestreURL : http://www.cheval2000.com/DESCRIPTION : ... Cherche petit cheval Cheval de couleur Rec herche Achetecheval bretagne 900 euros max ... du cheval, cheval bleu, che val noir ,cheval à vendre, randonnée cheval, cheval de course ...---TITRE : Cheval Francais : Les courses au trot en FranceURL : http://www.cheval-francais.com/DESCRIPTION : Découvrez le monde des courses au trot et ses hi ppodromes.Informations sur les activités et manifestations hippique s : calendriers,programmes et résultats officiels des courses.

REMARQUE 1.– La requête donnée en exemple 2 porte sur l’expressioncheval de:elle nécessite donc des guillemets pour exprimer au moteur que c’est bien cette sé-quence de mots qui est recherchée (conformément à la syntaxedes requêtes rappeléeen 10.3.1). Toutefois, les guillemets servent également dans une ligne de commande àdélimiter une unité (ici le paramètre). Il est donc nécessaire, en plus des guillemets dela ligne de commande d’insérer des guillemets précédés du caractère d’échappementhabituel (\ ) indiquant que le paramètre est une expression.

REMARQUE 2.– L’extrait de page Web introduit parDESCRIPTIONpeut en fait êtrede deux types. Si les auteurs de la page Web ont indiqué (commeil est possible dele faire en HTML) un texte résumant le contenu de leur page, c’est ce texte qui estaffiché, comme c’est le cas pour le deuxième document de l’exemple ci-dessus. S’iln’y a pas de résumé, c’est un extrait du document qui est fourni, autour du ou destermes de la requête. La distinction est formellement indiquée par la présence de pointsde suspension, qui indiquent un extrait. Dans le cas d’un résumé, les termes de larequête peuvent en être absents, ce qui peut poser un problème lors de l’explorationdu contexte des mots cherchés.

Détails du programme :

L’essentiel de ce programme est consacré à la communicationavec le moteur derecherche. Dans un premier temps, le programme lui transmetun ensemble d’infor-mations concernant la requête à traiter. En réponse, le moteur communique lui aussi

Page 370: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

378 Perl pour les linguistes

un ensemble d’informations, telles que le nombre de documents correspondants et lescaractéristiques des premiers documents les plus pertinents.

Avant de voir le détail des instructions Perl nécessaires à cette communication, ilconvient donc de détailler les différentes informations échangées, dont voici la liste etles codes correspondants :

– appid : l’identifiant Yahoo qui a été préalablement déclaré aux services de Ya-hoo ;

– query: le texte de la requête suivant la syntaxe habituelle (voir 10.3.1). La chaînecontenant la requête doit être codée enUTF-8;

– region : le pays où se trouve le serveur Yahoo interrogé. Par exemple, fr iden-tifie le serveur situé en France. Ce paramètre ne garantit pasque tous les documentsrenvoyés en réponse sont des documents hébergés en France, mais le serveur Yahoofrançais reste le plus apte à trouver des documents rédigés en français ;

– type : le type de requête, indiquant la façon dont le contenu de la requête doitêtre interprété par Yahoo si celle-ci contient plusieurs mots. Les valeurs possibles sontall (correspondant à une conjonction des termes),any (disjonction) ouphrase(pourune expression). Il est à noter que cette dernière valeur fait en quelque sorte doubleemploi avec l’utilisation de guillemets dans la requête ;

– results : le nombre maximal de documents renvoyés. La valeur maximale est100. Pour plus de réponses, il faut soumettre une nouvelle requête en modifiant leparamètrestart;

– start: le numéro du premier document demandé (à partir de 1). Cettevaleur n’estutilisée que lorsque l’on souhaite dépasser la limite de 100documents par requête ;

– format : le format des documents demandés. Les valeurs possibles sont any(n’importe quel format),html, pdf, etc. ;

– adult_ok : activation (0) ou désactivation (1) du filtre parental supprimant de laréponse les documents ayant un contenu pornographique;

– similar_ok : activation (0) ou désactivation (1) du système qui supprime de laréponse les documents jugés similaires ;

– language: la langue des documents recherchés, exprimée par un code dedeuxou trois lettres ;

– country : le pays où sont hébergés les documents recherchés, exprimépar uncode de deux lettres ;

– output : le format dans lequel est renvoyée la réponse, la seule valeur utilisablepar Perl étantXML .

Le détail de ces différents paramètres et des valeurs possibles est indiqué sur lapage :

http://developer.yahoo.com/search/web/V1/webSearch. html

Page 371: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Exploitation linguistique du Web 379

Les paramètres de la requête sont communiqués au moteur par le biais d’uneURL correspondant à une page dynamique, et les résultats sont simplement obte-nus par la fonctionget du moduleLWP::Simple . Toutefois, la complexité de cetteURL entraîne l’utilisation d’un module spécifique pour sa construction, le moduleURI::URL .

Le résultat de la recherche est, comme l’indique le dernier paramètre, exprimé enXML. La structure XML est assez simple, comme le montre le court extrait de lafigure 10.4, correspondant aux résultats de la requête"cheval de" (les lecteurspeu familiers avec XML peuvent se reporter au début du chapitre 9).

<?xml version="1.0" encoding="UTF-8"?><ResultSet

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instanc e"xmlns="urn:yahoo:srch"xsi:schemaLocation="urn:yahoo:srch http://api.search . ..."type="web"totalResultsAvailable="1020000"totalResultsReturned="100"firstResultPosition="1"moreSearch="/WebSearchService/V1/webSearch?query=%2 2cheval+ ...">

<Result><Title>Cheval de Troie - Wikipédia</Title><Summary>... Vos dons permettent à Wikipédia de continuer à

exister ! Merci de votre soutien. Cheval de Troie ... légenda ire,on a créé le terme &quot; Cheval de Troie &quot; pour parler d& apos;undon se ...</Summary>

<Url>http://fr.wikipedia.org/wiki/Cheval_de_Troie</ Url><ClickUrl>http://uk.wrs.yahoo.com/_ylt=A9iby5y6k. .. . </ClickUrl><DisplayUrl>fr.wikipedia.org/wiki/Cheval_de_Troie</ DisplayUrl><ModificationDate>1155625200</ModificationDate><MimeType>text/html</MimeType><Cache>

<Url>http://uk.wrs.yahoo.com/_ylt=A9iby5y6k. ... </Ur l><Size>25753</Size></Cache>

</Result>...

Figure 10.4.Extrait des résultats de la requête"cheval de"

Les informations disponibles les plus importantes sont :

– le nombre de documents indiqué dans l’attributtotalResultsAvailablede l’élé-ment racine (ResultSet) ;

– chaque document est décrit dans un élémentResult;

– dans ces éléments, l’URL, le titre et l’extrait/résumé sont respectivement insérésdans les élémentsUrl, Title etSummarysitués immédiatement sous l’élémentResult.

Page 372: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

380 Perl pour les linguistes

L’analyse de cette structure se fait dans le programme en utilisant le moduleXML::Simple , qui construit une structure de données complexe Perl correspon-dante, comme indiqué en 9.2.1 (page 328).

Le déroulement du programme est le suivant :

1) initialisation des chaînes contenant la requête et l’identifiant (lignes 11à 17).La requête devant être codée enUTF-8, un réencodage spécifique8 est effectuépar la fonctionencodedu moduleEncode , comme indiqué en annexe A2 (para-graphe A2.5.5 page 438) ;

2) construction de l’URLcorrespondant à la requête complète (lignes 19 à 35).Cette URL doit au final avoir la forme suivante (correspondant à la requêtecheval ) :

http://api.search.yahoo.com/WebSearchService/V1/web Search?appid=xxx&query=cheval&region=fr&type=phrase&results=10&start =1&format=html&adult_ok=1&similar_ok=0&language=fr&country=fr&outp ut=xml

On y voit les valeurs des différents paramètres codés sous unformat spécifiquecorrespondant à la norme HTML. S’il est possible de construire cette chaîne de façonclassique, le plus simple est d’utiliser les fonctionnalités du moduleURI::URL (quifait partie de la bibliothèquelwp ). Cette construction se fait en deux temps : toutd’abord la construction de l’URL de base, par la fonctionurl , puis l’encodage desparamètres par la fonctionquery_form ;

3) exécution de la requêteet récupération de la réponse au format XML (ligne 37)par la fonctionget du moduleLWP::Simple . La variable$reponse_yahoocontient le code XML de la réponse ;

4) test de la réponse(ligne 39 et lignes 56 à 58) : en cas de problème de commu-nication avec le moteur la valeur renvoyée est indéfinie et leprogramme indique unmessage d’erreur ;

5) analyse de la réponse XML(ligne 40) en utilisant la fonctionXMLin du moduleXML::Simple . Deux différences sont à noter avec le code présenté pour ce moduleen 9.2.1 (page 328). La première est que les données sont contenues cette fois dansla chaîne de caractères passée en premier paramètre (et non plus dans un fichier).La seconde est l’utilisation de l’optionForceArray, qui indique que dans la structurede données, les valeurs associées àResult doivent systématiquement être stockéesdans un tableau, même s’il n’y a qu’un seul élément de ce type.Sans cette option,l’analyse du code XML devrait s’adapter spécifiquement aux cas où un seul documentcorrespond à la requête ;

6) extraction et affichage des résultatsen se basant sur la structure de données$arbre_XML (lignes 41 à 54). Le nombre de documents est stocké dans la valeurassociée à la clétotalResultsAvailabledu hachage référencé par$arbre_XML . Si la

8. Si votre terminal est configuré enUTF-8, le recodage n’est pas nécessaire.

Page 373: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Exploitation linguistique du Web 381

réponse contient des résultats (donc si un contenu est associé au champResultdans$arbre_XML ), on en obtient la liste dans le tableau de hachages@resultats . Ilne reste plus dès lors qu’à parcourir ce tableau, et d’afficher pour chaque document lesinformations associées aux clésTitle, Url et Summary. Pour le titre et la descriptionde chaque document, la fonctionnormalise_latin1 est appliquée pour garantirl’affichage correct des lettres accentuées.

10.3.4. Interrogation automatique deLive Search: Live Search API

D’autres moteurs que celui vu précédemment proposent des services équivalents :le moteur de rechercheLive Search9 de la société Microsoft propose également unaccès automatique aux utilisateurs qui le souhaitent. Cet accès est toutefois limité à10 000 requêtes par jour, 50 documents par requête et doit répondre aux conditionsd’utilisation précisées sur leur site (les utilisations académiques à des fins non com-merciales sont permises). Le service correspondant a pour nom Live Search APIetpropose les fonctionnalités permettant de soumettre une requête et d’en recevoir lesrésultats par un programme.

Les fonctionnalités et les modalités d’accès à ce service sont décrites à l’URL :

http://dev.live.com/livesearch

10.3.4.1.Inscription et installation

L’accès à l’interrogation automatisée de Live Search nécessite avant tout une ins-cription au service. Cette inscription permet l’obtentiond’une clé, c’est-à-dire d’unidentifiant qui permet au fournisseur de ce service d’en contrôler l’accès. La clé estune chaîne de caractères qui doit être communiquée à chaque requête. Il est donc né-cessaire de demander (gratuitement) une clé au serviceLive Search APIpour pouvoirutiliser ce service. Elle est obtenue en remplissant le formulaire d’inscription en ligneà l’adresse suivante :

http://search.msn.com/developer/appids.aspx

Elle doit être insérée dans les programmes comme indiqué dans les exemples de codeci-dessous.

Du point de vue technique, l’utilisation de ce service nécessite un module Perlsupplémentaire :SOAP::Lite qui doit être installé spécifiquement.

REMARQUE.– Les programmes proposés sur le site de Live Search lors de l’inscrip-tion ne sont pas nécessaires, et correspondent à d’autres langages de programmationque Perl.

9. http://www.live.com . Ce moteur était par le passé connu sous le nom deMSN.

Page 374: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

382 Perl pour les linguistes

10.3.4.2.Exemple de programme : obtention de la liste des titres, URLset descrip-tions de documents pour une requête

Le programme Perl présenté ici possède les mêmes fonctionnalités querecherche-Yahoo.plet permet d’automatiser une requêtevia Live Search.

Listing 10.4 – recherche-Live.plInterrogation de Live Searchvia Live Search API

1 use strict;2 use locale;3 use SOAP::Lite;4 use XML::Simple;5 use Encode;6

7 if ( $#ARGV != 0 ) 8 die "Usage : $0 requete\n";9

10

11 my $requete = encode ("utf8", $ARGV[0]);12

13 #Insérez ci-dessous l’identifiant obtenu auprès de Live Se arch14 my $identifiant = "XXX" ;15

16 my $service = SOAP::Lite17 ->proxy("http://soap.search.msn.com:80/webservices. asmx?wsdl");18

19 my $requete_SOAP = prepare_requete ($requete, 0, 10);20

21 my $reponse = $service->Search( $requete_SOAP );22

23 if ( $reponse->fault )24 print "Erreur de Live Search : ", $reponse->faultdetail ;25 26 else 27 print "Total : ", $reponse->valueof( "//Total" ), "\n";28 my @resultats = $reponse->valueof( "//Result" );29 foreach my $document (@resultats)30 print "Titre : ",31 normalise_latin1 ( $document->"Title" ),"\n";32 print "URL : ", $document->"Url","\n";33 print "Description : ",34 normalise_latin1 ( $document->"Description" ),"\n";35 print "---\n";36 37 38

39 sub prepare_requete 40 my ( $r, $d, $n ) = @_;41 my $requete_structure = 42 "AppID" => [ $identifiant ],43 "Query" => [ $r ],44 "CultureInfo" => [ "fr-FR" ],45 "Requests" => [ 46 "SourceRequest" => [ 47 "Source" => [ "Web" ],48 "Offset" => [ $d ],49 "Count" => [ $n ] ]

Page 375: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Exploitation linguistique du Web 383

50 ]51 ;52 my $requete_XML = XMLout(53 $requete_structure, RootName=> "Request" );54 return SOAP::Data->type( "xml" => $requete_XML );55 56

57

58 sub normalise_latin1 59 ...60

Le code de la fonctionnormalise_latin1n’est pas reproduit ici pour raisons deplace. Il est présenté et décrit dans le programmeURL-texte.pl(listing 10.2).

Ligne de commande :perl recherche-Live.pl requête

Exemple :perl recherche-Live.pl cheval

Résultat :Les résultats sont similaires dans leur forme à ceux présentés pour recherche-Yahoo.pl.

Détails du programme :

Nous ne détaillerons ici que les différences entrerecherche-Live.plet recheche-Yahoo.pl, les structures générales des deux programmes étant similaires.

Les paramètres envoyés au moteur sont les suivants :

1) AppID : la clé d’identification ;

2) Query : la chaîne contenant la requête, qui doit utiliser la syntaxe décriteen 10.3.1 et être codée enUTF-8;

3) CultureInfo : la langue et la zone géographique à laquelle le moteur doit selimiter. La liste des codes disponibles est disponible sur le site deLive Search: lavaleurfr-FR indique des pages en français situées en France ;

4) Source: le type de réponse demandée au moteur de recherche. Nous nous limi-terons ici à la recherche de pages Web (Web) ;

5) Offset : le numéro du premier document souhaité (en partant de zéro). Ce pa-ramètre permet d’obtenir plus de 50 documents par requête enrépétant l’opération,comme cela est détaillé dans la section 10.4 ;

6) le nombre de documents souhaités (50 au maximum).

La réponse est renvoyée par le moteur sous la forme d’une structure de couples(champ, valeur). Les principaux champs utiles sont :

Page 376: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

384 Perl pour les linguistes

– Total : le nombre total de documents indexés correspondant à la requête. Il s’agiten réalité d’une estimation du nombre de documents dont il est possible d’avoir ledétail ;

– Results: la liste des documents renvoyés par la requête (50 au maximum parrequête).

Resultsest elle-même une liste de données comportant les informations suivantespour chaque document :

– Url : l’adresse du document disponible sur le Web ;

– Description: le résumé du document ou un très court extrait du document centrésur le ou les termes de la requête ;

– Title : le titre du document.

Tous les détails sur les paramètres et les résultats sont disponibles sur le site :

http://search.msn.com/developer/

La communication entre le programme d’interrogation et le moteur de recherchese fait par l’échange de données au format XML, en passant parle protocoleSOAP10.Ce protocole gère l’échange de données en XML à travers le Web, et son statut destandard a permis la mise à disposition de fonctionnalités dédiéesvia un module Perl.

Le déroulement du programme est le suivant :

1) initialisation de la chaîne contenant la requête (lignes 7 à 11), de la clé d’identi-fication (ligne 14) et du service (lignes 16 et 17). Ce dernierest représenté par un objetcomplexe défini par le moduleSOAP::Lite auquel il suffit de donner l’adresse duservice fourni parLive Search;

2) constructionde la structure de données contenant les paramètres de la requête.Cette opération se décompose elle-même en trois étapes et est réalisée dans le sous-programmeprepare_requete (lignes 39 à 55). Ce sous-programme, appelé enligne 19 reçoit trois paramètres : la chaîne contenant la requête, le numéro du pre-mier document demandé, et le nombre de documents demandés (maximum 50). Laconstruction de la structure complexe se fait de la façon suivante :

- construction d’une structure de données complexe Perl (contenue dans$requete_structure ) contenant les différents paramètres (lignes 41 à 51). Il s’agitici d’une requête Web demandant$n documents à partir du numéro$d correspondantau texte de la requête$r , rédigés en français et situés en France ;

- construction du document XML correspondant à cette structure (ligne 27).Cette opération se fait grâce à la fonctionXMLout du moduleXML::Simple . Cette

10. Simple Object Acess Protocol.

Page 377: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Exploitation linguistique du Web 385

fonction réalise l’opération inverse deXMLin , et construit une chaîne de caractèresXML à partir de la structure de données. L’optionRootName indique que la racine dudocument XML doit être l’élémentRequest . La chaîne de caractères correspondanteest stockée dans$requete_XML ;

- transformation de la requête au formatSOAP(ligne 28); afin de pouvoir êtretransmise au moteur de recherche. La variable$requete_SOAP contient une struc-ture de données complexe ;

3) transmissionde la requête et de ses paramètres au moteur de recherche par leprotocoleSOAP(ligne 21). La réponse obtenue est stockée dans un objet complet$reponse . Si le réseau ne permet pas de contacter le serveur, une erreur se situera àce stade et le programme s’arrêtera en indiquant la nature del’erreur ;

4) testde la bonne réception de la réponse (lignes 23 et 24). Si le moteur n’a pasaccepté la requête ou a renvoyé une réponse erronée, un message d’erreur sera affiché ;

5) affichage du nombre de documentsindexés correspondant à la requête(ligne 27) ;

6) extraction du tableau de résultats(ligne 28). Il est ensuite parcouru et chacunde ses éléments (lui-même stocké dans une référence à un hachage) est analysé ;

7) affichage, pour chaque document renvoyé, de son titre (Title), son adresse (Url )et sa description (Description). Cette dernière information peut être absente si elle n’apas été renseignée pour le document en question. Le titre et la description sont norma-lisés par la fonctionnormalise_latin1 vue pour le programmeURL-texte.pl.

10.3.5. Remarques sur l’interrogation automatique des moteurs de recherche

Les systèmes d’interrogation automatique des moteurs présentés ici sont encore endéveloppement. Ils sont donc susceptibles de modificationsconcernant leurs modesd’utilisation. Par ailleurs, les résultats de ces interrogations sont soumis à certainesprécautions :

Fiabilité des nombres de documents :le nombre total de documents contenantles termes de la requête, qui constitue une partie intéressante de la réponse du moteur,sont à interpréter avec précaution. Il convient tout d’abord de bien comprendre qu’ils’agit d’un nombre (approximatif) dedocuments, et nond’occurrencesdes termescherchés. Un document contenant plusieurs occurrences du terme ne comptera quepour une réponse ; le nombre d’occurrences est donc en théorie plus important quecelui indiqué. Par contre, de nombreux documents sont proposés en plusieurs exem-plaires (copies sur plusieurs sites, différentes version sur un même site, etc.) et ceci al’effet inverse, en augmentant artificiellement le nombre de résultats. Enfin, le nombreindiqué ne correspond que rarement au nombre effectif des documents dont on peutobtenir les adresses.

Page 378: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

386 Perl pour les linguistes

Requêtes contenant des caractères accentués :les moteurs ne font pas de diffé-rence claire entre une lettre accentuée (é, î, à) et le caractère de base correspondant(e, i, a) dans la chaîne correspondant à la requête. Ainsi, la requête congres et larequêtecongrès renvoient chacune les mêmes résultats.

10.4. Exemples d’utilisations complexes

Les programmes présentés jusqu’ici constituent les briques avec lesquelles des ap-plications plus complexes peuvent être construites. Les possibilités de ces techniquessont énormes et de nombreuses études peuvent être réaliséessur la base de pages Web.Deux exemples, basés sur une utilisation d’un moteur de recherche sont présentés ici.Le premier concerne la récolte des fréquences indiquées parun moteur de recherchepour une liste de mots, et le second réalise une extraction des contextes directementdans les pages renvoyées par le moteur. Avant de présenter ces programmes, nousévoquons les principales difficultés à traiter au vu du fonctionnement des programmesdéjà présentés.

10.4.1. Problèmes techniques à traiter

Les principales limites imposées par l’interrogation automatique d’un moteur derecherche sont :

– le programme ne soumet qu’une seule requête à la fois : il faut donc construireune boucle répétant l’ensemble du traitement (construction, exécution et analyse) ;

– l’accès aux seuls 50 (ou 100) premiers documents renvoyés par le moteur. Il fautalors réitérer une même requête en indiquant que l’on souhaite avoir accès aux 50 (ou100) documents suivants, en faisant varier le numéro du premier document demandé ;

– la limite fixée de quelques milliers de requêtes par jour : des campagnes degrande ampleur doivent alors s’étaler dans le temps. Le traitement ne doit pas êtrearrêté brutalement lorsque la limite est atteinte, mais simplement mis en attente jus-qu’à renouvellement du quota ;

– l’accès aux seuls extraits (ou résumés) des documents fournis par le moteur : ilest souvent nécessaire d’accéder au document lui-même en letéléchargeant entière-ment.

Ces problèmes sont résolus dans les exemples suivants. Les deux programmesprésentés ci-dessous utilisent chacun un moteur différent, mais les moteurs sont enréalité interchangeables ; l’adaptation du code ne concerne que les commandes liées àson interrogation.

Page 379: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Exploitation linguistique du Web 387

10.4.2. Calcul du nombre de documents indexés pour une liste de mots

Ce premier programme utilise l’API de Yahoo présentée précédemment. Il exem-plifie simplement l’utilisation massive de la technique de base. Son fonctionnementest le suivant : étant donnée une liste de mots stockée dans unfichier (sous la formed’un mot par ligne), le moteur de recherche Yahoo est interrogé successivement avecchacun de ces mots. En réponse, le programme affiche en sortiestandard le nombrede documents contenant ce mot.

Listing 10.5 – frequences-Yahoo.plCalcul du nombre de documents indexés par Yahoo pour une liste de mots

1 use strict;2 use locale;3 use Encode;4 use URI::URL;5 use LWP::Simple;6 use XML::Simple;7

8 if ( $#ARGV != 0 ) 9 die "Usage : ", $0, " fichier_requetes\n";

10 11

12 my $identifiant_Yahoo = "xxx"; #insérer l’identifiant ici13 my $url = url(14 "http://api.search.yahoo.com/WebSearchService/V1/we bSearch");15 open ( IN, "<", $ARGV[0] ) or16 die "Pb ouverture :", $ARGV[0], " :" , $!, "\n";17

18 while ( my $requete = <IN> )19 chomp $requete;20 $url -> query_form (21 appid => $identifiant_Yahoo,22 query => encode("utf8", $requete),23 region => "fr",24 type => "phrase",25 results => 0,26 start => 1,27 format => "html",28 adult_ok => 1,29 similar_ok=> 0,30 language => "fr",31 country => "fr",32 output => "xml"33 );34 my $reponse_xml = get $url;35 while ( not defined ($reponse_xml) )36 sleep (1000);37 $reponse_xml = get $url;38 39 my $arbre_XML = XMLin( $reponse_xml );40 my $nb_docs = $arbre_XML->"totalResultsAvailable";41 print $requete, "\t", $nb_docs, "\n";42 43

44 close (IN);

Page 380: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

388 Perl pour les linguistes

Ligne de commande :perl frequences-Yahoo.pl fichier_liste

Exemple :perl frequences-Yahoo.pl liste_animaux.txt

où liste_animaux.txta le contenu suivant :cheval

chien

chat

veau

vache

cochon

"crocodile volant"

"phacochère luisant"

Résultat :cheval 9190000

chien 8630000

chat 36800000

veau 2180000

vache 3660000

cochon 2240000

"crocodile volant" 56

"phacochère luisant" 0

REMARQUE.– Rappelons que les valeurs renvoyées sont sujettes à caution. Il est clairque les valeurs très hautes sont des approximations (quand elles atteignent plusieursmillions de documents). Pour les mots ou expressions plus rares, la valeur est net-tement plus précise. Notons enfin que la fréquence notablement plus élevée dechatprovient du terme emprunté à l’anglais désignant le dialogue en ligne sur Internet,largement surreprésenté dans les pages Web.

Détails du programme :

frequences-Yahoo.plse base bien entendu sur les mécanismes d’utilisation de Ya-hoo vus dansrecherche-Yahoo.pl(listing 10.3). Les modifications suivantes y ont étéapportées :

– une première phase supplémentaire consiste à ouvrir le fichier passé en para-mètre. Les requêtes individuelles y sont lues une par une dans une bouclewhile ;

– la requête envoyée au moteur utilise les mêmes paramètres que recherche-Yahoo.pl, à l’exception du nombre de documents demandés. Afin de ne pasencombrerinutilement le réseau, le nombre de documents demandés est fixé à zéro (paramètre

Page 381: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Exploitation linguistique du Web 389

results) ; cela n’a aucune incidence sur le nombre de documents indiqués par le mo-teur ;

– si la réponse de Yahoo n’est pas obtenue (que ce soit à cause d’un problème deréseau ou de dépassement du quota journalier de requêtes), le programme effectue unepause avant de réitérer la demande. La pause se fait à l’aide de la fonctionsleep, dontle paramètre est le nombre de secondes pendant lesquelles leprogramme ne fait plusrien. Ici 1000 secondes correspondent à un peu moins de 3 heures : ce programme estdonc conçu pour traiter de grandes listes de mots en plusieurs jours, afin de respecterles quotas imposés par Yahoo ;

– quand la réponse est obtenue, le mot de la requête est écrit en sortie standard,accompagné de la fréquence indiquée par Yahoo.

10.4.3. Extraction des contextes des termes de la requête

La seconde application, plus complexe, consiste en l’interrogation d’un moteur (iciYahoo) pour une requête unique, mais analyse systématiquement les documents ren-voyés en réponse. Ce programme,contextes-Yahoo.pl, combine donc l’utilisation d’unmoteur de recherche et le téléchargement d’un document donton connaît l’adresse(URL). L’exploitation proposée ici est simplement l’extraction des différents contextesd’apparition des mots de la requête dans le document, à la façon d’un concordancier.Le premier paramètre du programme est la requête transmise au moteur, et le secondest le nombre maximal de documents que le programme doit traiter.

Listing 10.6 – contextes-Yahoo.plExtraction des contextes des résultats de Yahoo pour une requête donnée

1 use locale;2 use strict;3 use URI::URL;4 use LWP::Simple;5 use XML::Simple;6 use HTML::Entities;7 use Encode;8

9 if ( $#ARGV != 1 ) 10 die "Usage : ", $0, " requete nombre_documents\n";11 12

13 my $requete = $ARGV[0];14 my $n_voulus = $ARGV[1];15

16 # NOTE : insérez ci-dessous l’identifiant que vous avez décl aré17 # auprès de Yahoo Web Search Services lors de votre inscripti on.18 # Reportez-vous au site http://developper.yahoo.com/19

20 my $identifiant_Yahoo = "xxx";21

22 my $url = url(

Page 382: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

390 Perl pour les linguistes

23 "http://api.search.yahoo.com/WebSearchService/V1/we bSearch");24

25 my $continuer = 1;26 my $decalage = 1;27 my $n_traites = 0;28 while ( $continuer ) 29 $url -> query_form (30 appid => $identifiant_Yahoo,31 query => encode("utf8", $requete),32 region => "fr",33 type => "phrase",34 results => 100,35 start => $decalage,36 format => "html",37 adult_ok => 1,38 similar_ok=> 0,39 language => "fr",40 country => "fr",41 output => "xml"42 );43

44 my $reponse_yahoo = get( $url );45 while ( not defined ($reponse_yahoo) ) 46 sleep (1000);47 $reponse_yahoo = get $url;48 49 my $arbre_XML = XMLin($reponse_yahoo, ForceArray =>["Res ult"]);50 if (defined ($arbre_XML->"Result") ) 51 my @documents = @$arbre_XML->"Result";52 while ( ($#documents >= 0) and ($n_traites < $n_voulus) )53 my $document = shift @documents;54 my $ok = traite_url ( $document->"Url" );55 if ( $ok == 1 )56 $n_traites++;57 58 59 if ( ($n_traites >= $n_voulus) or60 ($decalage+100 >=61 $arbre_XML -> "totalResultsAvailable") ) 62 $continuer = 0;63 64 else 65 $decalage = $decalage + 100;66 67 68 else 69 $continuer = 0;70 71 72

73 sub traite_url 74 my $url = shift @_;75 my $page = get( $url );76 if ( defined ($page) )77 print "---\nURL : $url\n";78 my $codage_page = "latin1";79 if ( $page =~ /\bcharset * = * ([\w-]+)/i ) 80 $codage_page = $1;81 eval decode ($codage_page, "test") ;82 if ( defined ($@) ) 83 $codage_page = "latin1";

Page 383: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Exploitation linguistique du Web 391

84 85 86 my $page_unicode = decode( $codage_page, $page );87 my $texte_unicode = supprime_html( $page_unicode ) ;88 my $texte = normalise_latin1 ( $texte_unicode );89 $texte =~ s/\n/ /g;90 my $requete_texte = $requete;91 $requete_texte =~ s/\"//g;92 while ( $texte =~ /\b$requete_texte\b/ig )93 my $contexte_gauche = substr($‘, ( length($‘)-20), 20);94 my $contexte_droit = substr($’, 0, 20);95 print $contexte_gauche."|".$&."|".$contexte_droit."\ n";96 97 return 1;98 99

100

101

102 sub normalise_latin1 103 ...104 105

106 sub supprime_html 107 ...108

Ligne de commande :perl contextes-yahoo.pl requête nombre_documents

Exemple :perl contextes-yahoo.pl "\"cheval de\"" 30

Résultat (extrait) :---

URL : http://www.le-site-cheval.com/

ère lui son dernier |cheval de| bataille ; l’associ

---

URL : http://www.chevalcomtois.com/

iation Nationale du |Cheval de| Trait Comtois Bienv

iation Nationale du |Cheval de| Trait Comtois 2003

---

URL : http://www.maisonslaffitte.net/musee.htm

Contact Le musée du |cheval de| courses Vous complè

visite du musée du |cheval de| courses. Le musée d

ourses. Le musée du |cheval de| courses est install

Dreux" en 1998, le |cheval de| Bronze en 2001, ou

ections du Musée du |Cheval de| Courses possédent q

---

URL : http://www.cheval-haute-ecole.com/

---

Page 384: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

392 Perl pour les linguistes

REMARQUE.– On remarque dans cet extrait qu’un même document peut contenir plu-sieurs occurrences des termes de la requête, ce qui n’est pasle cas lorsque l’on se baseuniquement sur l’extrait fourni par le moteur. De plus, il arrive que certains documentsne contiennent pas les termes recherchés ; c’est le cas du quatrième document de notreexemple. Cette absence peut avoir plusieurs causes :

– le document n’est pas accessible, soit à cause de la fermeture ou du changementd’adresse du site qui l’hébergeait, soit à cause d’un incident réseau ;

– les mots de la requête se trouvent dans une partie du document non analysée parle programme, par exemple dans l’entête ;

– les mots n’apparaissent pas dans la page sous la forme exacte de la requête (dif-férence d’accents ou problème de segmentation du texte) ;

– le contenu de la page a été modifié depuis son indexation par le moteur de re-cherche. Rappelons que la « vision » du Web par un moteur de recherche est en retardpar rapport à la réalité des sites ;

– les mécanismes d’indexation des moteurs sont parfois pluscomplexes que lesimple repérage de chaînes de caractères dans les pages. Au final, ils peuvent prendrela décision d’associer une page avec un mot-clé sans que celui-ci soit présent dans lapage.

Détails du programme :

contextes-yahoo.plutilise les fonctionnalités d’interrogation de Yahoo vuesdansrecherche-yahoo.pl(listing 10.3). Par rapport à ce programme, les modifications sontles suivantes :

– la même requête est soumise plusieurs fois au moteur, qui nefournit au maxi-mum que 100 documents. A chaque interrogation le paramètrestart de la requête estmodifié. Chaque passage dans la boucle principale du programme traite ainsi 100 do-cuments renvoyés par Yahoo. Ceci se répète jusqu’à ce que le nombre de documentsindiqués par l’utilisateur soit atteint, ou jusqu’à épuisement des documents renvoyéspar Yahoo. Cette progression est contrôlée par la variable$decalage , qui est ini-tialisée à 1 et augmente de 100 à chaque itération. La condition sous laquelle l’inter-rogation du moteur doit se poursuivre étant complexe, le programme gère la variable$continuer , qui vaut 1 si le traitement doit se poursuivre, et zéro si le traitementest terminé ;

– afin de permettre l’analyse d’un grand nombre de documents,les quotas imposéspar Yahoo sont gérés de la même façon que dans le programme précédent : en cas denon-réponse du moteur, une pause de 1000 secondes (un peu moins de 3 heures) esteffectuée avant de relancer la requête ;

– une fois qu’une réponse a été obtenue, la série de documentsrenvoyée va êtreparcourue, soit entièrement soit en partie si le nombre de documents voulus est atteint.Chaque document est analysé en utilisant la fonctiontraite_url détaillée plus

Page 385: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Exploitation linguistique du Web 393

loin. Notons qu’un document n’est comptabilisé que s’il a pueffectivement être traité,c’est-à-dire si la valeur de retour de la fonctiontraite_url vaut 1 ;

– une fois qu’une série de documents a été analysée, un test permet de savoir siune prochaine série de 100 documents doit être demandée. Le programme s’arrêtera(en positionnant la variable$continuer à zéro) si le nombre de documents voulupar l’utilisateur a été atteint, ou bien s’il n’y a plus de documents à analyser par épui-sement des réponses du moteur ;

– le traitement de chaque document est effectué par la fonction traite_url . Ilcomporte trois parties :

- la page est téléchargée, transformée en texte brut et recodée enLatin1commedans le programmeURL-texte.pl(listing 10.2). Ce traitement fait appel aux fonctionssupprime_html et normalise_latin1 dont le code est identique à celui deURL-texte.pl et n’est donc pas reproduit ici. Si la page n’a pu être obtenue, aucuntraitement ne s’effectue, et la valeur de retour de la fonction sera indéfinie, le documentinaccessible n’étant pas comptabilisé ;

- deux transformations supplémentaires sont réalisées avant la recherche pro-prement dite : les retours à la ligne présents dans le texte dela page sont suppriméset remplacés par des espaces afin de ne pas perturber l’affichage des contextes, et leséventuels guillemets présents dans la requête transmise aumoteur sont supprimés. Lesguillemets n’ont en effet de sens que pour le moteur, et ne doivent pas être recherchésdans le texte de la page ;

- le texte de la requête est ensuite recherché dans le contenutextuel de la page,en utilisant un expression régulière. Pour chaque occurrence, le contexte (gauche etdroit) est calculé en utilisant une version simplifiée des mécanismes des concordancesvus au chapitre 7.

Ce programme peut aisément être adapté pour procéder à un autre type d’exploi-tation des documents. Il serait ainsi possible de :

– stocker le contenu des documents dans des fichiers textes etainsi constituer au-tomatiquement un corpus ;

– effectuer des calculs lexicométriques au voisinage des mots de la requête ;

– vérifier automatiquement des hypothèses sur les contextesen les testant systé-matiquement.

Ce ne sont bien sûr que des exemples et non une liste exhaustive : l’ensemble destraitements de données textuelles présentés dans cet ouvrage peuvent s’appliquer aucontenu des pages Web ainsi obtenues.

Page 386: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

394

Page 387: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

ANNEXE 1

Préparation des données

Cette annexe présente en détails quelques programmes qui effectuent des traite-ments préparatoires sur les données. Certains de ces programmes sont utilisés dans lechapitre 2, d’autres sont destinés à être utilisés ponctuellement en fonction des don-nées sélectionnées.

Les traitements réalisés par ces programmes sont de trois types :

– le nettoyage et la normalisation des documents, ce qui comprend la conversiondes fins de ligne, la suppression des entêtes des fichiers et ladésambiguïsation de lalemmatisation produite par leTreeTagger;

– la segmentation en mots d’un texte brut ;

– l’application à un ensemble de fichiers d’un traitement Perl ou d’un programmeexternevia des appels système.

A1.1. Conversion des retours à la ligne

Le paragraphe 1.4.1.2 (page 42) présente le codage des fins deligne des documentscréés sur des systèmes Unix et Windows. Rappelons que sur lesmachines Unix, lesretours à la ligne sont représentés par le caractère LF (line feed) tandis que sous Win-dows ils le sont par la séquence de caractères CR-LF (carriage returnsuivi de linefeed). Le comportement de la plupart des applications Windows, et notamment del’interpréteur Perl, est indifférent à l’absence du CR dansles documents provenant desystèmes Unix. Lors de la lecture du fichier, les CR sont ajoutés de façon implicite. Iln’est donc pas nécessaire de réaliser une conversion des finsde ligne pour ces fichiers.En revanche, beaucoup d’applications Unix ne traitent pas correctement les textes is-sus de Windows et considère le CR comme un caractère à part entière, faisant partie

395

Page 388: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

396 Perl pour les linguistes

de la chaîne qui le précède. Il est donc impératif de convertir les fins de ligne de cesfichiers. En Perl, le caractère CR est désigné par le code\r .

Le programme suivant réalise la conversion en supprimant les CR qui se trouventen fin de ligne.

Listing A1.1 – conversion-fins-ligne.plConversion des fins de ligne Windows sous Unix

1 use strict;2 use locale;3

4 while( my $ligne = <STDIN> )5 $ligne =~ s/\r$//;6 print $ligne;7

Ligne de commande :perl conversion-fins-ligne.pl < fichier_Windows > fichier_Unix

Exemple :perl conversion-fins-ligne.pl < texte_windows.txt >

texte_unix.txt

Détails du programme :

Le programme lit successivement les lignes sur l’entrée standardSTDIN et en sup-prime le caractère\r qui se trouve à la fin (ligne 5). Les lignes sont ensuite affichéessur la sortie standard. Il n’est pas nécessaire d’éliminer le caractère\n parchomppuisde le restaurer.

A1.2. Segmentation en mots

La segmentation en mots est une étape importante dans l’exploitation des textes.Les fichiers qui les contiennent sont en effet des séquences de caractères ou de lignesqui n’ont pas de signification particulière du point de vue linguistique. La segmenta-tion en mots est notamment utile pour réaliser des traitements sur les unités lexicales,comme la recherche de formes (voir paragraphe 5.2.1 page 192). Notons que la seg-mentation en phrases découle de celle en mots : les séquencesde mots comprises entredeux ponctuations fortes peuvent être utilisées comme des approximations relative-ment fiables des phrases.

Le résultat de la segmentation d’une ligne (ou d’un texte) est généralement pré-senté sous un formatverticalisé, où chaque mot ou signe repéré est placé seul sur uneligne.

Page 389: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Préparation des données 397

Nous présentons dans cette section deux programmes de segmentation. Le premierest très simple. Il opère un découpage grossier qui ignore lapolysémie des principauxséparateurs de mots : espace, virgule, apostrophe, tiret etpoint. Le second permet untraitement plus fin de ces éléments typographiques en s’appuyant notamment sur uneliste d’exceptions étendue.

A1.2.1. Version simple

Le premier programme réalise une segmentation grossière car systématique, baséesur les espaces, les signes de ponctuation et les symboles. Ces trois catégories peuventêtre décrites au moyen des classes de caractères prédéfiniesdes expressions régulièresouvia les propriétés Unicode des caractères (voir paragraphe 4.3.1.1, page 169).

Listing A1.2 – segmentation-mots-simple.plSegmentation grossière d’un texte en mots et signes de ponctuation

1 use strict;2 use locale;3 while (my $ligne = <STDIN>)4 chomp($ligne);5 my @mots1 = split(/(\pP|\pS|\s)/, $ligne);6 my @mots2 = grep(/\S/, @mots1);7 print join("\n", @mots2), "\n";8

Ligne de commande :perl segmentation-mots-simple.pl < texte_brut > texte_segmenté

Exemple :perl segmentation-mots-simple.pl < tordre1.txt > tordre1 .seg

Entrée (extrait) :des compagnies d’assurance, par des voyageurs de commerce,

etc., etc. En général, 1

Résultat correspondant à l’entrée précédente :

descompagniesd’assurances

1. A se tordre, d’Alphonse Allais, fichiertordre1.txt.

Page 390: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

398 Perl pour les linguistes

,pardesvoyageursdecommerce,etc.,etc.Engénéral,

Détails du programme :

La segmentation en mots par le programmesegmentation-mots-simple.plest réa-lisée ligne par ligne, en découpant chacune d’elles suivantles espaces, signes de ponc-tuation et symboles.

Ce découpage est effectué par la fonctionsplit appliquée à une ligne de texte.L’expression régulière qui décrit les points de découpe estla suivante :

/(\pP|\pS|\s)/

Elle indique bien que la segmentation se fait sur :

– les signes de ponctuation (ceux ayant la propriété UnicodeP, en correspondanceavec\pP , par exemple les virgules, les points, etc.) ;

– les symboles (propriétéS, en correspondance avec\pS , commeC, §, etc.) ;

– les espaces (classe prédéfinie\s , qui comprend les espaces simples, les espacesinsécables et les tabulations).

La fonctionsplit permet de préserver, dans la liste qu’elle renvoie, les sous-chaînesqui ont constitué les points de segmentation. Il suffit pour cela d’entourer l’expressionrégulière de parenthèses.

Nous détaillons ci-dessous les étapes de segmentation pourla ligne suivante où lesespaces sont représentés par des:

- Superbe ! On ne s’en lasserait jamais.

La segmentation se base sur les séparateurs indiqués entre crochets :

[-][ ]Superbe[ ][!][ ]On[ ]ne[ ]s[’]en[ ]lasserait[ ]jamais[.]

Page 391: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Préparation des données 399

Ce qui au final donne en sortie desplit un tableau qui contient à la fois les segments(même vides) qui se trouvent entre deux séparateurs, et les séparateurs :

("","-",""," ","Superbe"," ","","!",""," ","On"," ","ne"," ",

"s"," ","’"," ","en"," ","lasserait"," ","jamais",".")

Le résultat de cette première étape n’est pas satisfaisant car le tableau@mots1contient de nombreuses chaînes vides, là où deux séparateurs étaient consécutifs,comme dans le cas des espaces qui suivent ou précèdent les signes de ponctuation(ou dans le cas, non exemplifié ici, de plusieurs espaces ou signes de ponctuationconsécutifs). De plus, les espaces constituent également des éléments de ce tableau,alors qu’ils ne sont pas souhaités dans le texte segmenté2.

La seconde étape du traitement consiste donc à filtrer le tableau@mots1à l’aidede la fonctiongrep pour éliminer les éléments réduits à la chaîne vide ou à un espace.Le critère de filtrage est décrit par l’expression régulière/\S/ . grep préserve ainsiles chaînes qui contiennent au moins un caractère autre qu’un espace. Le résultat pourl’exemple ci-dessus est conservé dans le tableau@mots2 :

("-", "Superbe", "!", "On", "ne", "s", "’", "en", "lasserai t",

"jamais", ".")

Le résultat de cette segmentation est satisfaisant pour lesunités qui ne sont consti-tuées que de lettres (grosso modo, les mots simples). Elle est en revanche systémati-quement erronée pour les unités plus complexes qui contiennent des signes de ponc-tuation comme les abréviations, les élisions ou les mots composés. Par exemple,etc.

produirait deux segments,etc et . ; de même, le tiret demachine-outil donneraittrois segmentsmachine , - etoutil . Le programmesegmentation-mots-exceptions.plprésenté ci-dessous permet de segmenter ce type d’unités d’une façon plus appropriée.

A1.2.2. Segmentation avec des exceptions

La principale différence entre la version élaborée du segmenteur proposée ci-dessous et la précédente est la prise en compte d’un ensembleétendu d’exceptionsdont certaines sont intégrées au programme et d’autres fournies par l’utilisateur. Lesexceptions dont le traitement est codé danssegmentation-mots-exceptions.plsont lestrois points (...), les séquences de chiffres qui contiennent des espaces, des points oudes virgules, les pronoms inversés (doit-il), les formes élidées (commel’ dansl’écoleou il l’entend), etc. Les autres exceptions doivent être définies par l’utilisateur, commeles locutions (rendez-vous, d’abord, curriculum vitae, au fur et à mesure, R et D), les

2. Les espaces n’étant que des séparateurs, ils sont inutilesdans un texte verticalisé où ce rôleest rempli par les fins de ligne.

Page 392: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

400 Perl pour les linguistes

abréviations (resp. (respectivement),chap. (chapitre),c.-à-d. (c’est-à-dire),etc. (etcaetera), E/S(entrée/sortie)), des éléments de mise en page (1°, 2°) et plus générale-ment toutes les unités que le programme doit préserver lors du découpage.

Ces exceptions sont communiquées au programme par le biais d’un fichier de textedont le nom est passé en argument.

Listing A1.3 – segmentation-mots-exceptions.plSegmentation en mots fine qui respecte une liste d’exceptions définie par l’utilisateur

1 use strict;2 use locale;3 if ($#ARGV != 0)4 die "Usage : ", $0, " EXCEPTIONS\n";5 6 open(EXCEP, "<", $ARGV[0]) or die "impossible d’ouvrir ", $ ARGV[0];7 my %exception;8 while (my $ligne = <EXCEP>)9 chomp($ligne);

10 $exception$ligne = 1;11 12 close(EXCEP);13 my @excepqm;14 foreach my $e (sort length($b) <=> length($a) keys (%exce ption))15 push(@excepqm, quotemeta($e));16 17 my $excepre = join("|", @excepqm);18 while(my $ligne = <STDIN>)19 chomp($ligne);20 $ligne =~ s/(^|\pNonPT|\s|\.\.\.)($excepre)(\pNo nPT|\s

|\.\.\.|$)/$1<PPLcut>$2<PPLcut>$3/g;21 my @res;22 foreach my $seg (split(/<PPLcut>/, $ligne))23 if (defined($exception$seg))24 push(@res, $seg);25 26 else 27 $seg =~ s/(\d)\s(\d)/$1<PPLesp>$2/g;28 foreach my $m (split(/(\pNonAmb|\s|\.\.\.)/, $seg))29 if ($m eq "..." or $m =~ /^\pNonAmb$/)30 push(@res, $m);31 32 elsif ($m !~ /^\s * $/)33 $m =~ s/(\PL|^)([cdjlmnst]\’)/$1\t$2\t/ig;34 $m =~ s/(\PL|^)(\pL * [q][u]\’)/$1\t$2\t/ig;35 $m =~ s/([\pL\d]+\.([\pL\d]+\.)+)/\t$1\t/g;36 $m =~ s/\.$/\t./;37 $m =~ s/(\D|^),/$1\t,\t/g;38 $m =~ s/,($|\D)/\t,\t$1/g;39 $m =~ s/-t-(elle|elles|en|il|ils|on|y)($|\PL)/\

t-t-\t$1\t$2/ig;40 $m =~ s/-(ce|elle|elles|en|il|ils|je|la|le|leur

|les|lui|moi|m\’|nous|on|toi|tu|t\’|vous|y)($|\PL)/\t-\t$1\t$2/ig;

41 $m =~ s/(\pP)(\pP)/\t$1\t$2\t/g;42 $m =~ s/<PPLesp>/ /g;

Page 393: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Préparation des données 401

43 $m =~ s/([<>])/\t$1\t/g;44 push(@res, (split(/\t/, $m)));45 46 47 48 49 my @res1 = grep(/./, @res);50 if (@res1)51 print join("\n", @res1), "\n" ;52 53 54 sub NonPT55 return "+utf8::P\n+utf8::S\n-002D\n-002E"56 57 sub NonAmb58 return "+utf8::P\n+utf8::S\n-0027\n-002C\n-002D\n-00 2E\n-003C\n

-003E"59

Ligne de commande :perl segmentation-mots-exceptions.pl exceptions < texte_brut >

texte_segmenté

Exemple :perl segmentation-mots-exceptions.pl exceptions.txt <

tordre1.txt > tordre1.seg

Fichier d’exceptions (extrait) :

M.MM.apr. J.-C.arc-en-cielav. J.-C.et al.etc.f.a.q.suppl.rendez-vous

Entrée (extrait) :des compagnies d’assurance, par des voyageurs de commerce,

etc., etc. En général,

Résultat :

descompagniesd’assurances

Page 394: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

402 Perl pour les linguistes

,pardesvoyageursdecommerce,etc.,etc.Engénéral,

Détails du programme :

La stratégie mise en œuvre dans le programmesegmentation-mots-exceptions.plconsiste à préserver en priorité les exceptions fournies par l’utilisateur. La segmenta-tion se déroule en trois temps : 1) les exceptions de l’utilisateur sont d’abord identifiéespuis séparées ; 2) le programme resegmente ensuite les tronçons compris entre des ex-ceptions sur la base des espaces, des symboles et des ponctuations autres que point,virgule, tiret et apostrophe ; 3) chacun des segments obtenus est redécoupé une nou-velle fois en tenant compte des valeurs des quatre signes de ponctuation laissés de côtépar l’étape précédente.

Le programme commence par lire le fichier d’exceptions fourni par l’utilisateurcomme premier argument ($ARGV[0] ). Le fichier contient une exception par ligne.Les exceptions sont stockées comme clés du hachage%exception (ligne 10). Ellessont utilisées une première fois pour repérer dans les points de coupe de premier ni-veau en insérant dans ces positions une marque<PPLcut> 3 (ligne 20). Les marquessont insérées au moyen d’une substitution chaque fois qu’une exception est isolable,c’est-à-dire comprise entre deux séparateurs tels qu’un signe de ponctuation autre quele point et le tiret, un symbole, un espace ou une séquence de trois points. Une pro-priété UnicodeNonPTestdéfinieà cette fin. Cette définition prend dans le programmela forme d’une fonction (lignes 54 à 59) dont le nom est celui de la propriété à dé-finir et qui retourne une chaîne de caractères indiquant que cette propriété est vraiepour tous les signes de ponctuation (propriété UnicodeP) et les symboles (propriétéUnicodeS) autres que le point et le tiret. Ces deux caractères sont désignés par leurspoints de codeUnicode, à savoir 002E et 002D (voir paragraphe A2.5.2). La syntaxegénérale de cette définition est assez simple : elle doit êtrecontenue dans une chaînede caractères où chaque ligne indique les caractères à ajouter (+) ou à supprimer (-) de

3. Cette séquence arbitraire et improbable garantit qu’ellepermettra d’identifier sans ambiguïtéces points de coupe par la suite.

Page 395: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Préparation des données 403

la liste. Une fois définie, la propriété est utilisable dans une expression régulière parla notation\p propriété , donc ici\pNonPT .

Les chaînes de caractères fournies par l’utilisateur ne peuvent cependant pas êtreutilisées directement car elles peuvent contenir des caractères qui appartiennent aulangage des expressions régulières, notamment des points et des tirets. Elles doiventêtre au préalable recodées au moyen de la fonctionquotemeta(ligne 15) ;quotemetacrée une copie de la chaîne initiale dans laquelle tous les caractères qui font partiede la syntaxe des expressions régulières sont échappés. Lesexceptions recodées sontstockées dans le tableau@excepqm(ligne 15), puis réunies parjoin en une expressionrégulière disjonctive stockée dans$excepre (ligne 17). Par ailleurs, la règle de miseen correspondance « de gauche à droite » sélectionne dans la disjonction le premierélément qui peut être apparié avec une partie de la ligne de texte à segmenter (voirsection 4.5, page 174). L’ordre d’apparition des éléments dans la disjonction est doncimportant. Par exemple, siC. apparaît dans la disjonction avantC. adm. , ce dernierne sera jamais repéré, la mise en correspondance se faisant toujours avecC. . Pouréviter ce problème, les exceptions sont triées par ordre de longueur décroissante afinque les plus longues apparaissent avant les plus courtes (ligne 14).

Les lignes du texte sont découpées au niveau des marques<PPLcut> en utilisantsplit (ligne 22). Le programme considère ensuite successivementles tronçons obte-nus. Ceux qui correspondent à des exceptions (ligne 23) sontconservés tels quelsdans la liste@res des segments résultats (ligne 24). Les autres sont découpésà nou-veau relativement aux espaces, symboles et signes de ponctuation et les séquences detrois points qui y apparaissent (ligne 28). Cependant, les points, les virgules, les apos-trophes et les tirets ne sont pas pris en compte pour cette deuxième segmentation ; ilfont l’objet de traitements spécifiques ultérieurs (lignesà 32 à 45). Les chevrons< et> sont également traités séparément (ligne 43) car ils apparaissent dans les marquesqui sont ajoutées par le programme, notamment<PPLesp> utilisée pour protéger lesséquences de chiffres (\d ) qui incluent des espaces (par exemple1 234 567ne doit pasêtre séparé en trois unités1, 234et567). <PPLesp> est substitué aux espaces contenusdans ces séquences avant qu’elles ne soient découpées (ligne 27). Les espaces peuventainsi être restitués dans leur position d’origine à la fin du traitement (ligne 42).

A l’inverse du premier, le deuxième découpage est réalisé sans prémarquage despoints de coupe. Les séparateurs sont listés directement dans l’expression régulièrefournie àsplit. Il s’agit d’une disjonction qui comprend trois éléments :

1) les ponctuations et les symboles autres que point, virgule, tiret, apostrophe, che-vron droit et chevron gauche sont représentés par une nouvelle propriété UnicodeNonAmbdéfinie sous la forme d’une fonction (lignes 60 à 69) ;

2) les espaces sont désignés au moyen de la classe prédéfinie\s qui regroupe lesespaces, les tabulations et les retours à la ligne ;

3) les séquences de trois points.

Page 396: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

404 Perl pour les linguistes

L’expression régulière utilisée pour ce deuxième découpage est entourée de paren-thèses pour indiquer àsplit qu’elle doit également retourner les sous-chaînes qui ontconstitué les points de découpage.

Les segments obtenus à la suite de ce deuxième découpage sontanalysés tour àtour. Les séquences de trois points et les caractères ayant la propriétéNonAmbsontsimplement ajoutées à@res (lignes 29 à 31). Les segments qui ne contiennent quedes caractères d’espacement sont ignorés.

Les autres segments sont soumis à une série d’expressions régulières (lignes 33à 41) qui insèrent des points de coupe en fonction des ponctuations, puis à un der-nier découpage au moyen de la fonctionsplit (ligne 44) ; les segments obtenus sontajoutés à la liste@res. La marque utilisée pour les points de coupe est le caractèredetabulation\t qui est initialement absent de ces segments :

1) les deux premières substitutions (lignes 33 et 34) concernent les mots quicontiennent des apostrophes et qui doivent être détachés, àsavoir les prépositions (d’),déterminants (c’, l’ , quelqu’), particule (n’), pronoms (j’ , m’, t’ , l’ , s’) et autres formesen-qu’ (qu’, jusqu’, lorsqu’, presqu’) ;

2) les points sont traités par les deux substitutions suivantes (lignes 35 et 36). Lapremière isole les sigles constitués de séquences de lettres ou de chiffres séparés pardes points commeO.N.U.ou E.U. La deuxième détache les points qui sont suivis parune autre ponctuation (c’est-à-dire un point, une virgule,un tiret ou une apostrophe).La troisième insère un point de coupe avant les points qui se trouvent à la fin d’unsegment. Ces derniers n’étant inclus ni dans une exceptions, ni dans une abréviationsont des marques de fin de phrase ;

3) les deux substitutions suivantes (lignes 37 et 38) séparent les virgules qui setrouvent en début (resp. fin) de segment, à condition qu’elles ne soient pas précédées(resp. suivies) d’un chiffre ;

4) les tirets sont détachés lorsqu’ils apparaissent devantun pronom sujet inversé(comme danspuis-je), éventuellement précédé d’une liaison-t- comme dansaffirme-t-on (lignes 39 et 40) ;

5) la substitution de la ligne 41 sépare les séquences de ponctuations restantes.

La dernière partie du programme élimine les segments vides créés par les traite-ments précédents et les affiche. Le nettoyage est réalisé parla fonctiongrep (ligne49) qui élimine ici les éléments de la liste@res qui ne contiennent pas au moins uncaractère, quel qu’il soit.

Les segments non vides sont conservés dans une liste@res1 dont les élémentssont affichés (ligne 51). Le test de la ligne 50 permet d’éviter l’affichage d’un retour àla ligne lorsque@res1 est vide.

Page 397: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Préparation des données 405

A1.3. Suppression des entêtes de fichier du corpus de l’ABU

La suppression des entêtes et plus généralement l’extraction du texte d’un docu-ment est une opération généralement simple, mais spécifiqueà chaque corpus ou sous-partie de corpus. Elle n’est donc pas réutilisable. Nous proposons ici un programmequi permet de traiter les entêtes des fichiers qui composent le corpus de l’ABU (voirparagraphe 1.5.1.4, page 58). Ces entêtes se composent de lalicence ABU complétéepar des informations métatextuelles ou de nature éditoriale.

REMARQUE.– Le texte de la licence ABU ne doit bien entendu être supprimé desfichiers qu’afin de faciliter leur traitement. Il doit être restauré systématiquement àl’identique lors de toutediffusiondes textes, même si ceux-ci ont été modifiés par untraitement spécifique, conformément au contenu de la licence.

L’ensemble des textes du corpus présente une structure uniforme : l’ordre d’appa-rition des éléments qui composent les entêtes et les délimiteurs utilisés sont identiquespour dans tous les fichiers. Plus précisément, le début du texte des documents est si-gnalé par une ligne de la forme :

-------------------- DEBUT DU FICHIER ... -------------- -------

où ... représente le nom du fichier. La fin du texte est marquée par uneligne simi-laire :

-------------------- FIN DU FICHIER ... ---------------- -------

Le programme qui extrait le texte d’un document est donc trèssimple. Il consiste àlire les lignes du fichier sur l’entrée standard et à ne les écrire sur la sortie standardque si l’on a déjà rencontré le marqueur de début mais pas encore celui de fin.

Listing A1.4 – suppression-entete-ABU.plSuppression des entêtes des fichiers du corpus de l’ABU

1 use strict;2 use locale;3

4 my $dans_texte = 0;5 while( my $ligne = <STDIN> )6 if( $ligne =~ / FIN DU FICHIER / )7 $dans_texte = 0;8 9 if( $dans_texte )

10 print $ligne ;11 12 if( $ligne =~ / DEBUT DU FICHIER / )13 $dans_texte = 1;14 15

Page 398: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

406 Perl pour les linguistes

Ligne de commande :perl suppression-entete-ABU.pl < fichier_ABU > fichier_nettoyé

Exemple :perl suppression-entete-ABU.pl < tordre1.abu > tordre1.t xt

Détails du programme :

Ce programme lit une à une les lignes du fichier et maintient une variable$dans_texte qui indique si l’on se trouve à l’intérieur ou à l’extérieur du texte. Elleest positionnée à 1 (qui correspond à la valeur booléenne VRAI) si la ligne qui vientd’être lue se trouve à l’intérieur du texte et à 0 (qui correspond à la valeur booléenneFAUX) sinon. Ce programme suppose que le fichier est bien formé et qu’il contient unseul marqueur de début de texte et un seul de fin de texte. Par ailleurs, l’identificationdes marqueurs est réalisée en s’appuyant sur la présence deschaînes de caractèresDEBUT DE FICHIERet FIN DE FICHIER .

L’ordre des trois conditionnelles qui composent le corps dela boucle est important.Au départ,$dans_texte est initialisée à 0 (ligne 4), le marqueur de début n’ayant pasencore été rencontré. La variable est aussi positionnée à 0 si le marqueur de fin de texteest trouvé (lignes 6 à 8). Ainsi, le séparateur n’est pas recopié sur la sortie standardpar la conditionnelle suivante (lignes 9 à 11). Enfin,$dans_texte est positionnée à 1si le marqueur de début est présent dans la ligne courante (lignes 12 à 14). De ce fait,le séparateur de début de texte n’est pas affiché par la conditionnelle qui la précède(lignes 9 à 11). Contrairement à la quasi-totalité des programmes de ce livre, les fins deligne ne sont pas ici supprimées de$ligne par la fonctionchomp: les lignes du textesont en effet recopiées telles quelles sur la sortie standard et leur analyse au moyendes expressions régulières des lignes 6 et 12 n’est pas affectée par la présence de cescaractères terminaux.

A1.4. Désambiguïsation de la lemmatisation duTreeTagger

Le TreeTagger, le catégoriseur utilisé dans ce livre, propose pour certains motsdes lemmatisations multiples (c’est-à-dire sous-déterminées). C’est par exemple lecas de noms féminins commecafetière(dont le lemme estcafetièrequand c’est unappareil etcafetierquand c’est un humain qui tient un café) oucanadienne(dont lelemme estcanadienquand il s’agit d’un ressortissant du Canada etcanadiennesi c’estune tente). Des lemmatisations ambiguës sont également produites pour les adjectifs(chatouilleuseest le féminin dechatouilleuret dechatouilleux), les verbes (suisestune forme fléchie deêtreet desuivre), les pronoms personnels (lesest le pluriel à lafois dele et dela), etc.

Page 399: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Préparation des données 407

Dans tous ces cas, leTreeTaggerpropose l’ensemble des lemmes possibles séparéspar des barres verticales :

cafetière NOM cafetier|cafetièrecanadienne NOM canadien|canadiennechatouilleuse ADJ chatouilleux|chatouilleurla DET:ART la|lesuis VER:pres suivre|être

Ces ambiguïtés sont tout à fait justifiées en sortie d’un étiqueteur morphosyn-taxique, puisque les lever relève d’un mécanisme sémantique. Effectuer automatique-ment un choix nécessiterait donc des ressources et des techniques totalement diffé-rentes, et dont la complexité dépasse largement les utilisations présentées dans cetouvrage.

Les lemmatisations sous-spécifiées sont toutefois gênantes parce qu’elles sont dif-ficiles à utiliser. Comment faut-il traiter ces mots quand onveut par exemple compterle nombre de lexèmes différents qui apparaissent dans un texte ? Le même problèmese pose si l’on souhaite extraire d’un texte les instances d’un patron dont les élémentspeuvent avoir des lemmes ambigus. Il est naturellement possible de modifier les pro-grammes afin qu’ils puissent gérer ces lemmatisations sous-spécifiées mais cela en-traîne une complexification importante, et inutile car il s’agit d’une limite techniquedu catégoriseur et que ces mots n’ont pas du point de vue linguistique un intérêt par-ticulier.

Une solution plus simple et pratique consiste à sélectionner pour chacune deces lemmatisations un seul élément. C’est ce qui est réalisépar le programmedesambiguisation-lemmatisation.plqui utilise une liste de désambiguïsation pourchoisir un lemme pour chaque occurrence à lemmatisation ambiguë. La désambiguï-sation proposée est statique : les lemmes sont sélectionnésune fois pour toute pourl’ensemble de leurs occurrences. Par exemple, toutes les occurrences de la forme ver-balesuis reçoivent le lemmeêtre car l’auxiliaire est beaucoup plus fréquent que leverbesuivre. De même,canadienneest systématiquement lemmatisé encanadiencarcanadienest une forme nominale plus fréquente dans les textes quecanadienne; il estdonc plus probable que ce soit la forme canonique du lexème nominal. Ces décisionssont rassemblées dans une liste compilée par un programme à partir d’un corpus degrande taille en utilisant quelques heuristiques simples basées sur la fréquences deslemmes non ambigus, sur celle des formes, etc. La liste indique, pour chaque motcatégorisé ayant une lemmatisation ambiguë, le lemme qu’ildoit recevoir :

concubines NOM concubin|concubine concubineconcubine NOM concubin|concubine concubineconvient VER convenir|convier convenirconverse NOM convers|converse conversconverse ADJ convers|converse conversecoordonnées NOM coordonnée|coordonnées coordonnée

Page 400: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

408 Perl pour les linguistes

copieuse ADJ copieur|copieux copieuxcopieuses ADJ copieur|copieux copieux

La liste peut être corrigée par l’utilisateur ou complétée pour traiter des ambiguïtésqui n’ont pas encore été rencontrées. Le programme suivant projette ces désambiguï-sations sur les textes catégorisés par leTreeTagger.

Listing A1.5 – desambiguisation-lemmatisation.plDésambiguïsation de la lemmatisation duTreeTagger

1 use strict;2 use locale;3

4 if ( $#ARGV != 0 )5 die "Usage : ", $0, " TABLE_DESAMBIGUISATION\n";6 7 open(AMB, "<", $ARGV[0]) or die "impossible d’ouvrir ", $AR GV[0];8 my %desamb;9 while ( my $ligne = <AMB> )

10 chomp($ligne);11 my ($forme, $tag, $lemme_amb, $lemme) = split(/\t/, $ligne );12 $desambjoin("\t", $forme, $tag, $lemme_amb) = $lemme;13 14 close(AMB);15 while ( my $ligne = <STDIN> )16 if ( $ligne =~ /\|/ )17 chomp($ligne);18 my ($forme, $tag, $lemme) = split(/\t/, $ligne);19 my $cat = $tag;20 $cat =~ s/:. * $//;21 my $entree = join("\t", lc $forme, $cat, lc $lemme);22 if (defined($desamb$entree))23 print join("\t", $forme, $tag, $desamb$entree),"\n";24 25 else26 print $ligne, "\n";27 warn $ligne, " <= ambiguïté absente dans ", $ARGV[0];28 29 30 else31 print $ligne;32 33

Ligne de commande :perl desambiguisation-lemmatisation.pl liste_de_désambiguïsation

< texte_catégorisé > texte_désambiguïsé

Exemple :perl desambiguisation-lemmatisation.pl desamb.txt < tor dre1.tt

> tordre1.tag

Page 401: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Préparation des données 409

Entrées (fragments) :

je PRO:PER jepouvais VER:impf pouvoirles PRO:PER la|leregarder VER:infi regarder, PUN ,...la DET:ART leNorvégienne NOM norvégien|norvégienne, PUN ,...je PRO:PER jene ADV nesuis VER:pres suivre|êtrequ’ KON que...car KON carsix NUM sixmois NOM moi|moisaprès KON après

Résultats (fragments) :

je PRO:PER jepouvais VER:impf pouvoirles PRO:PER leregarder VER:infi regarder, PUN ,...la DET:ART leNorvégienne NOM norvégien, PUN ,...je PRO:PER jene ADV nesuis VER:pres êtrequ’ KON que...car KON carsix NUM sixmois NOM moisaprès KON après

Détails du programme :

Ce programme a une structure classique, très simple : 1) il stocke la table de désam-biguïsation dans un hachage ; 2) projette les lemmes présélectionnés sur les mots am-bigus. Les ambiguïtés « inconnues » (c’est-à-dire absentesde la table) sont reproduitestelles quelles en sortie, mais le programme les signale en affichant un message d’er-reur.

Page 402: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

410 Perl pour les linguistes

Dans la première partie (lignes 7 à 14), le programme lit le fichier des ambiguïtés.Les lignes de ce dernier comportent 4 champs : la forme, la catégorie (sans attribut), laliste des lemmes possibles (séparés par des barres verticales) et le lemme sélectionné.Les trois premiers éléments correspondent aux lignes des fichiers de textes catégoriséspar leTreeTaggerpour les mots à lemmatisation ambiguë. Ils sont stockés, joints pardes tabulations, comme clés du hachage%desamb. Le quatrième champ de chaqueligne est le lemme qu’il faut utiliser pour le mot décrit par les trois premiers. Il estassocié à ces derniers comme valeur dans le hachage%desamb(ligne 12).

Dans la deuxième partie (lignes 15 à 33), le programme lit le fichier catégorisé àdésambiguïser sur le flux d’entrée standard (ligne 15). Les lignes qui ne contiennentpas de barre verticale sont recopiées sans modification sur le flux de sortie stan-dard (lignes 30 à 32). Celle qui contiennent des ambiguïtés se répartissent en deuxgroupes :

1) pour les ambiguïtés qui figurent dans la table, le programme remplace sim-plement les lemmes initiaux par celui qui a été présélectionné (lignes 22 à 24). Leséléments de la ligne sont mis au format des clés du hachage%desambpar suppressiondes attributs de l’étiquette (lignes 19 et 20), passage en minuscules de la forme et dulemme, puis jointure par des tabulations (ligne 21) ;

2) pour les autres, les lignes d’entrée sont recopiées sur lasortie standard. Unmessage d’erreur est ensuite affiché au moyen de la fonctionwarn (lignes 25 à 28).

Ce programme peut être appliqué à des fichiers contenant des textes catégorisés,mais il peut aussi être intégré comme post-traitement à la commande qui réalise l’appelauTreeTagger. Cette seconde option est implémentée sous Windows dans le fichier decommandetag-french-desamb.batet sous Linux danstree-tagger-french-desamb.

A1.5. Application d’un traitement à un ensemble de fichiers

Il arrive fréquemment que l’on ait besoin d’appliquer un traitement non pas à unseul fichier mais à une collection de documents. C’est le cas par exemple si l’on veutcréer un corpus catégorisé à partir des 277 textes de l’ABU ousi l’on souhaite com-parer le nombre de néologismes qui y apparaissent. Les différents traitements (sup-pression des entêtes, étiquetage, désambiguïsation des lemmes, extraction des néolo-gismes) doivent alors être répétés pour chaque texte.

Le langage Perl dispose d’un ensemble de fonctions adaptéesà la manipulation desfichiers et des répertoires qui facilitent l’itération de ces traitements, comme présentéen section 5.6 (page 224) pour la recherche dans plusieurs fichiers. Deux exemplesplus complexes sont proposés ici. Le premier est la suppression des entêtes ABU detous les fichiers en.abu d’un répertoire qui lui est fourni en paramètre. Le second ap-plique un programme externe, en l’occurrence leTreeTagger, à l’ensemble des fichiersen.txt d’un répertoire.

Page 403: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Préparation des données 411

REMARQUE.– L’environnement de travail fourni sur le site Web d’accompagnementcontient déjà les résultats des traitements présentés ici,en ce qui concerne le corpusABU. Les programmes ne sont donc pas destinés à être exécutéssur ces fichiers, maissur de nouvelles données obtenues par l’utilisateur (aprèsadaptation des différentsparamètres le cas échéant).

A1.5.1. Suppression des entêtes ABU dans un ensemble de fichiers

Le programme suivant supprime les entêtes ABU de tous les fichiers d’un réper-toire, en créant pour chaque fichier dont le nom se termine par.abu un fichier résultatayant le même nom, mais avec une extension.txt . Son code reprend intégralementcelui desuppression-entete-ABU.plen l’incluant dans une boucle qui itère le traite-ment sur tous les fichiers en.abu du répertoire passé en paramètre. Le programmeinforme l’utilisateur de la progression du traitement en affichant sur le flux d’erreurstandard le nom des fichiers résultats au fur et à mesure de leur création.

Listing A1.6 – suppression-entetes-ABU-repertoire.plSuppression des entêtes de tous les fichiers ABU qui se trouvent dans un répertoire

1 use strict;2 use locale;3

4 if ( $#ARGV != 0 )5 die "Usage : ", $0, " REPERTOIRE\n";6 7 my $repertoire = $ARGV[0];8 opendir(REPERTOIRE, $repertoire) or9 die "impossible d’ouvrir le répertoire ", $repertoire, "\n ";

10 my @fichiers = grep(/\.abu$/, readdir(REPERTOIRE));11 closedir(REPERTOIRE);12 foreach my $fic (@fichiers)13 my $res = $fic ;14 $res =~ s/^(. * )\.abu$/$1.txt/;15 print STDERR $res, "\n";16 open(ENTREE, "<", $repertoire."/".$fic) or17 die "impossible d’ouvrir ", $repertoire."/".$fic;18 open(SORTIE, ">", $repertoire."/".$res) or19 die "impossible d’ouvrir ", $repertoire."/".$res;20 my $dans_texte = 0;21 while(my $ligne = <ENTREE>)22 if($ligne =~ / FIN DU FICHIER /)23 $dans_texte = 0;24 25 if($dans_texte)26 print SORTIE $ligne ;27 28 if($ligne =~ / DEBUT DU FICHIER /)29 $dans_texte = 1;30 31 32 close(SORTIE);33 close(ENTREE);34

Page 404: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

412 Perl pour les linguistes

Ligne de commande :perl suppression-entetes-ABU-repertoire.pl répertoire_ABU

Exemple :perl suppression-entetes-ABU-repertoire.pl C:\PPL\Corpus\ABU

Sous Unix, le répertoire du corpus ABU est :~/PPL/Corpus/ABU .

Détails du programme :

Le programme comporte deux parties : la création de la liste@fichiers desfichiers du répertoire à traiter et l’itération du traitement sur chacun d’eux.

Il commence par stocker dans$repertoire le chemin du répertoire qui lui estpassé en paramètre ($ARGV[0] ). Il l’ouvre ensuite au moyen de la fonctionopendir etlui associe le descripteurREPERTOIRE(ligne 8). Le contenu du répertoire est ensuitelu au moyen dereaddir . La liste produite par cette commande est filtrée pargrep afinde ne conserver que les noms de fichier qui se terminent par.abu (c’est-à-dire ceuxqui satisfont l’expression régulière/\.abu$/ ; ligne 10). Une fois la liste constituée,le répertoire est fermé en utilisant la fonctionclosedir (ligne 11).

La seconde partie du programme (lignes 12 à 34) est une boucledans laquelle,pour chaque fichier$fic à traiter, le programme calcule le nom du fichier résultat$res en substituant l’extension.txt à .abu (lignes 13 et 14). Il affiche sur le fluxd’erreur standard (STDERR) un message qui prévient l’utilisateur que le fichier$res

va être créé (ligne 15). Les chemins des fichiers sont reconstitués en faisant précéderleurs noms,$fic et $res , par le chemin du répertoire et le séparateur ‘/ ’ (ce quifonctionne aussi bien sous Windows que sous Unix, voir section 5.6). Les deux fichierssont ensuite ouverts et associés aux descripteursENTREEet SORTIE (lignes 16 à 19).Le reste du programme reprend le code desuppression-entete-ABU.pl(listing A1.4).Une fois le traitement terminé, les deux fichiers sont fermés(lignes 32 et 33).

A1.5.2. Catégorisation d’un ensemble de fichiers

Le programme suivant ne diffère desuppression-entetes-ABU-repertoire.plquepar le fait que le traitement des fichiers, en l’occurrence leur catégorisation, est sous-traité auTreeTagger. Autrement dit, le programme Perl va lui-même entraîner l’exécu-tion d’une série de commandes par le système d’exploitation, en construisant à chaquefois une chaîne de caractères correspondant à la ligne de commande, telle qu’elle seraitmanuellement saisie par un utilisateur, et en la communiquant au système.

Le programmecategorisation-repertoire.plprend comme argument un répertoire,dans lequel il va appliquer leTreeTaggerà tous les fichiers dont l’extension est.txt ,et stocker le résultat de la catégorisation dans un fichier en.tag .

Page 405: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Préparation des données 413

Listing A1.7 – categorisation-repertoire.plCatégorisation des fichiers qui se trouvent dans un répertoire

1 use strict;2 use locale;3

4 if ( $#ARGV != 0 )5 die "Usage : ", $0, " REPERTOIRE\n";6 7 my $repertoire = $ARGV[0];8

9 opendir(REPERTOIRE, $repertoire) or die10 "Impossible d’ouvrir le répertoire ", $repertoire, "\n";11 my @fichiers = grep( /\.txt$/, readdir(REPERTOIRE) );12 closedir(REPERTOIRE);13

14 foreach my $fic ( @fichiers )15 my $res = $fic ;16 $res =~ s/^(. * )\.txt$/$1.tag/;17

18 print STDERR $res, "\n";19 ‘tag-french-desamb.bat $repertoire\\$fic > $repertoire \\$res‘;20 # Sous Unix, remplacer la ligne précédente par :21 # ‘tree-tagger-french-desamb $repertoire/$fic22 # > $repertoire/$res‘;23

Ligne de commande :perl categorisation-repertoire.pl répertoire

Exemple :perl categorisation-repertoire.pl C:\PPL\Corpus\ABU

Sous Unix, le répertoire du corpus ABU est :~/PPL/Corpus/ABU .

Détails du programme :

Les lignes 1 à 18 de ce programme sont identiques à celles desuppression-entetes-ABU-repertoire.pl. Seules changent les extensions.txt et .tag des fichiers en en-trée et en sortie. La ligne 19 est en revanche différente. Il s’agit d’un appel au sys-tème d’exploitation invoquant la commandetag-french-desamb.bat4 avec comme pa-ramètre d’entrée le fichier$fic (désigné par son chemin$repertoire\\$fic )et une redirection de la sortie dans le fichier$res (désigné par son chemin$repertoire\\$res ). L’appel au système se fait en entourant la chaîne de carac-tères contenant la commande par des apostrophes inversées (‘ ). Dans cette ligne decommande, le séparateur des noms de fichiers et de répertoires sous Windows ‘\ ’

4. Sous Unix, la commande à exécuter esttree-tagger-french-desamb, et la ligne de code n°19est donc à modifier, comme indiqué dans les commentaires des lignes 20 à 22.

Page 406: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

414 Perl pour les linguistes

est échappé en le faisant précéder d’une autre barre obliquearrière5. Les variables$repertoire , $fic et $res sont interpolées, c’est-à-dire remplacées par leurs va-leurs, les noms du répertoire et des fichiers qu’elles contiennent. La ligne de com-mande obtenue est ensuite transmise telle quelle au systèmequi l’exécute.

5. Lors d’un appel au système, les séparateurs qui figurent dans les éventuels chemins ne sontpas adaptés par Perl aux différents types de systèmes d’exploitation, comme le fait le pro-gramme A1.6. Le programmeur doit donc réaliser lui-même la transposition du séparateur.

Page 407: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

ANNEXE 2

Codage des caractères

Les données manipulées dans cet ouvrage étant essentiellement des chaînes decaractères, certaines considérations liées à la représentation interne de ceux-ci (c’est-à-dire au codage des caractères) sont nécessaires. Cette annexe aborde les aspectstechniques généraux du codage des caractères, présente lesprincipaux codages utili-sés pour manipuler les langues d’Europe occidentale, aborde les problèmes les pluscourants liés à la multiplicité des codages et en donne des solutions directement ap-plicables.

A2.1. Généralités

Les données de texte brut, quelles qu’elles soient (textes,lexiques, etc.) sont sto-ckées sur un support numérique en attribuant à chaque caractère distinct une valeurnumérique spécifique. Ces valeurs dépendent de normes établies, oucodes, suiviespar les logiciels et programmes servant à écrire, lire et utiliser ces données.

Le fait qu’il existe plusieurs types d’alphabets implique une multiplicité des sys-tèmes de codage. De plus, il existe différents standards pour des jeux de caractèressimilaires, comme notamment ceux utilisés par les langues d’Europe occidentale. Cesdifférents codes, incompatibles entre eux pour la plupart,sont dus à des différencesentre les systèmes d’exploitation, mais aussi à des raisonshistoriques.

A2.1.1. Rapide historique du codage des caractères

La problématique du codage des caractères remonte aux débuts de l’informatique.Les premiers codes utilisés avaient notamment pour but d’économiser l’occupation

415

Page 408: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

416 Perl pour les linguistes

en mémoire des données de type texte, et couvraient des jeux de caractères très li-mités. Les premiers codes ne couvraient que 32 caractères (c’est-à-dire les 26 lettresde l’alphabet latin, sans distinction de casse, plus quelques séparateurs). Le code leplus répandu fut stabilisé en 1967 : le codeASCII1, standard nord-américain qui esttoujours d’actualité dans le monde informatique, a été validé depuis par l’organisationinternationale de standardisation (ISO).

Ce code comporte 128 caractères, dont 32 caractères non affichables ou caractèresde contrôle. Ceux-ci sont présentés plus en détails dans la table A2.3.

Les 96 caractères affichables définis dans le codeASCII sont les suivants, dansl’ordre de leurs valeurs numériques :

! " # $ % & ’ ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < => ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z[ \ ] ^ _ ‘ a b c d e f g h i j k l m n o p q r s t u v wx y z | ~

La valeur numérique associée à chacun de ces caractères est indiquée dans le ta-bleau A2.4.

Si ce code est tout à fait suffisant pour représenter des textes en langue anglaise,il ne contient aucun caractère accentué et ne peut suffire à représenter un texte enfrançais par exemple.

A la suite de ce code, un certain nombre d’extensionsont été définies par lesprincipaux constructeurs de systèmes et de logiciels pour coder les caractères man-quants. Ces extensions consistent en autant de jeux de 128 caractères ajoutés à ceuxdu codeASCII. Les principaux jeux permettant de coder des caractères accentués sontprésentés ci-dessous, mais à titre d’exemple voici la listedes caractères affichablesajoutés pour constituer le codeLatin1 (qui sera décrit plus en détails par la suite) :

¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ - ® ¯ ° ± 2 3 ´ µ ¶ · ¸ 1 º » ¼ ½¾ ¿ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø ÙÚ Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õö ÷ ø ù ú û ü ý þ ÿ

Comme on peut le voir en regardant cette liste, les lettres accentuées du français s’ytrouvent toutes incluses, en casse haute et basse. On y trouve également d’autres ca-ractères, permettant de coder correctement des textes écrits dans les langues suivantes

1. American Standard Code for Information Interchange, ou code standard américain pourl’échange d’information.

Page 409: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Codage des caractères 417

(liste non exhaustive) : albanais, allemand, anglais, basque, catalan, danois, espagnol,finnois, indonésien, islandais, italien, malais, néerlandais, norvégien, portugais, swa-hili, suédois.

D’autres systèmes de codage ont également été définis pour les principaux alpha-bets (grec, cyrillique, arabe, hébreu, phonétique, etc.),ainsi que pour d’autres carac-tères basés sur l’alphabet latin, mais utilisant des diacritiques différents (notammentpour les langues d’Europe centrale et orientale).

Le principe de base pour ces autres jeux de codage est de préserver systémati-quement le codeASCII, et d’ajouter une centaine de caractères, parfois communs àplusieurs jeux de codage. Ces différents codes ont donc en commun le nombre decaractères représentés (256) ce qui, techniquement, revient à représenter un caractèrepar un octet c’est-à-dire 8 bits. On parlera ainsi de codagessur 8 bits.

Cet état de fait n’est pas satisfaisant pour plusieurs raisons :

– certains caractères ont été omis pour des raisons de place.C’est notamment lecas duœdans le jeu de caractèresLatin1;

– de nouveaux caractères apparaissent, comme le symbole de l’euro (C) ;

– certains textes multilingues nécessitent plusieurs codes dans un même fichier.Un lexique français-arabe par exemple ne peut être codé par un seul jeu de caractères.

Pour répondre aux deux premiers problèmes, de nouveaux standards ont été défi-nis. Ainsi, une version révisée de l’extension de l’alphabet latin est apparue en 1998,incluant le symbole de l’euro et ajoutant certains caractères oubliés pour le françaiset le finnois, au détriment de certains symboles peu usités (voir la description du codeLatin9en paragraphe A2.2.3).

Pour le troisième problème (mais aussi pour des raisons encore plus vitales, no-tamment l’harmonisation du codage des langues asiatiques), les organisations inter-nationales de standardisation ont défini un système de codage dit « universel ». Cesystème de codage a été une révolution après des années de multiplication des jeuxde codage. Il propose un mode unique de représentation des caractères, quelle quesoit leur origine linguistique. Ce système est connu sous lenom d’Unicode. Il s’agitplus précisément d’une norme, attribuant un code unique (appelépoint de code) àdes dizaines de milliers de caractères, permettant ainsi dedépasser les limites des jeuxexistants et de simplifier la manipulation des textes multilingues. Ce nouveau standardpermet également d’unifier les différents codes pour le mêmealphabet.

A2.1.2. Polices de caractères

L’affichage de caractères par un système informatique (que ce soit à l’écran ouviaune imprimante) nécessite de plus unepolice de caractères, c’est-à-dire une liste de

Page 410: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

418 Perl pour les linguistes

dessins (ouglyphes) associés à chaque caractère. Les polices sont bien connuespourse différencier par leur style et la forme précise des caractères qu’elles représentent,mais elles se distinguent également par le codage sous-jacent qu’elles supposent.

Ainsi, disposer d’un fichier de texte dans un code particulier n’est pas suffisant :encore faut-il qu’une police adéquate soit disponible pourpouvoir l’afficher ou l’im-primer. Il est donc parfois nécessaire de modifier la police de caractères utilisée parun éditeur de texte ou un terminal. Toutefois, du point de vuedu traitement par unprogramme, les polices ne sont pas à prendre en considération.

A2.1.3. Conséquences pour le traitement linguistique

Les conséquences de cette multiplication des codes sont nombreux, et concernentdirectement les linguistes manipulant des données électroniques. La première est lanécessité de s’interroger sur le codage d’une ressource textuelle électronique lors de sacréation. De même, la grande variété des ressources linguistiques disponibles, notam-mentvia Internet, a des origines diverses et peut confronter rapidement leur utilisateurà différents codages.

La plupart des problèmes découlent du fait que les fichiers detexte ne contiennentpas d’information sur le type de codage qui a été utilisé pourles créer. Par contre,tout logiciel ou programme manipulant des ressources textuelles s’attend à trouverdes données codées d’une certaine façon, et aura un comportement incorrect si laréalité n’est pas conforme à son attente. A titre d’exemple,une situation malheu-reusement classique est celle qui conduit un éditeur de texte à afficher un texte (icila phrase «Différentes façons de fâcher un bœuf.» ) sous les formessuivantes :

1) Différentes façons de fâcher un b 1/2uf.

2) DiffÚrentes faþons de fÔcher un b¢uf.

3) Diff rentes fa ons de f cher un b uf.

4) Différentes façons de fâcher un bÅuf.

Ces affichages peu lisibles sont tous dus à l’utilisation d’un codage non adaptépour interpréter un même fichier de données. Cet exemple, surlequel nous revenonsau paragraphe A2.4.2, permet de voir que certains codes sontincompatibles entre eux,au sens qu’ils :

– ne définissent pas exactement les mêmes caractères, ce qui donne le cas 1 où laligatureœest remplacée par un autre caractère ;

– attribuent des valeurs numériques différentes aux mêmes caractères, ce quidonne les cas 2 et 3 pour les lettres accentuées, où celles-cisont remplacées pard’autres lettres, des symboles arbitraires (comme) ou bien ne sont pas affichéesdu tout ;

Page 411: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Codage des caractères 419

– n’utilisent pas le même système de représentation numérique, auquel cas certainscaractères sont remplacés par plusieurs symboles au lieu d’un seul (cas 4).

L’explication concrète des situations menant à ce type d’affichage est donnée dansle tableau A2.1.

En plus de ces difficultés d’affichage et de lecture, de nombreux problèmes de trai-tement peuvent survenir si l’on n’y prend pas garde, et peuvent invalider certainesrésultats. Certains caractères du français sont notoirement complexes à manipulersous format électronique, dont les apostrophes et les ligaturesœet Œ (voir para-graphe A2.6.3). Certains caractères sont mêmes difficiles àsaisir au clavier : dans cecas, il faut faire appel à des fonctionnalités avancées des éditeurs de texte, ou utiliserdirectement le code numérique du caractère voulu (voir paragraphe A2.5.2).

A2.2. Principaux codages utilisés

Parmi les dizaines de codages disponibles à l’heure actuelle, nous ne détaillons icique ceux qui permettent de représenter les langues d’Europeoccidentale, ou celles uti-lisant le même alphabet qu’une de ces langues. Le lecteur intéressé par des alphabetsdifférents peut trouver en bibliographie des références pour aborder cette question, etlire avec profit la partie de ce chapitre dédiée au codage Unicode.

A2.2.1. ASCII

Le codageASCII étant le premier standard historique, il est manipulable sans lemoindre souci sur tout système d’exploitation et par tout logiciel traitant des donnéesde type texte. Son problème principal est qu’il ne permet pasde représenter les carac-tères accentués, ce qui constitue une limite inacceptable pour les textes en français. Laliste des caractères affichables de ce codage est rappelée ci-dessous :

! " # $ % & ’ ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < => ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z[ \ ] ^ _ ‘ a b c d e f g h i j k l m n o p q r s t u v wx y z | ~

A2.2.2. Latin1

Le codageLatin1 (également appeléISO-Latin1ou ISO-8859-1) est le premierstandard international proposant une extension au codeASCII destiné au codage deslangues d’Europe occidentale. La liste des caractères supplémentaires qu’il définit estla suivante :

Page 412: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

420 Perl pour les linguistes

¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ - ® ¯ ° ± 2 3 ´ µ ¶ · ¸ 1 º » ¼ ½¾ ¿ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø ÙÚ Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õö ÷ ø ù ú û ü ý þ ÿ

Son statut de standard en fait le codage par défaut de nombreux logiciels, prin-cipalement dans le monde Unix. C’est également le codage pardéfaut pour les pro-grammes Perl, à la fois pour le code source des programmes, mais aussi pour lesdonnées d’entrée et de sortie.

A2.2.3. Latin9

Le codageLatin9 (également appeléISO-Latin9ou ISO-8859-15) est en fait unemise à jour du codagelatin1, rendue inévitable après l’apparition de l’euro, et qui apermis également de corriger certains oublis lors de la définition deLatin1. La liste descaractères supplémentaires (par rapport au codeASCII) qu’il définit est la suivante :

¡ ¢ £ C ¥ Š § š © ª « ¬ ® ¯ ° ± 2 3 Ž µ ¶ · ž 1 º » Œ œŸ ¿ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø ÙÚ Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õö ÷ ø ù ú û ü ý þ ÿ

Les différences entreLatin1etLatin9sont peu nombreuses,Latin9ayant remplacé8 caractères peu usités deLatin1par d’autres jugés nécessaires :

Latin1 Latin9¤ C¦ Š¨ š´ Ž¸ ž¼ Œ½ œ¾ Ÿ

Si un texte enLatin9 est interprété comme étant enLatin1, tous les caractères dela colonne de droite seront affichés en utilisant ceux de la colonne de gauche.

Page 413: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Codage des caractères 421

A2.2.4. CP1252

CP1252(ou Windows-1252ou ANSI2 ou encoreMS-ANSI) est un codage définipar la société Microsoft, apparu avec les premiers systèmesWindows. Il est devenule standard des systèmes de cette famille pour les langues occidentales. Il présentede grandes similarités avec les standardsISO, et plus particulièrement avecLatin1.Toutefois,CP1252contient des caractères supplémentaires, notamment des signes deponctuation comme les guillemets-apostrophes (“ ”) et les points de suspension (. . . ),les ligatures œ et Œ et le symbole de l’euro (C). Apparu avantLatin9, il est toutefoisincompatible avec celui-ci au regard de ces trois derniers caractères, puisqu’il leurattribue des valeurs numériques différentes (voir tableauA2.4).

La liste des caractères supplémentaires que définitCP1252est la suivante :

C , f „ ... † ‡ ˆ ‰ Š ‹ Œ Ž ‘ ’ “ ” • - -- ~ ™ š › œ žŸ ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ® ¯ ° ± 2 3 ´ µ ¶ · ¸ 1 º » ¼ ½¾ ¿ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø ÙÚ Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õö ÷ ø ù ú û ü ý þ ÿ

Au total,CP1252compte plus de caractères affichables queLatin1etLatin9. Cettedifférence tient au fait que ces deux derniers codages contiennent des caractères decontrôle supplémentaires, essentiellement pour des raisons de compatibilité.

Les différences entreCP1252etLatin1posent un ensemble de problèmes. La plu-part des logiciels de traitement linguistique, ainsi que lelangage Perl lui-même, consi-dèrent queLatin1est le codage par défaut. Les problèmes ne concernent dans laréalitéque quelques caractères de ponctuation, mais que l’on rencontre fréquemment dans lestextes rédigés en utilisant les outils de Microsoft (comme le traitement de texte Word).Ces problèmes spécifiques sont abordés en A2.6.3.

A2.2.5. CP850

Avant les systèmes Windows et la définition duCP1252, Microsoft utilisait pourson système d’exploitation DOS une autre extension du codeASCII pour les languesd’Europe occidentale. Celui-ci, baptiséCP850(également appeléMultilingual Latin1 ou Dos Latin 1, ) est encore utilisé dans les terminaux sur les plate-formes Win-dows (sous toutes ses versions configurées en français à ce jour). Ce jeu de caractèrescontient toutes les lettres accentuées nécessaires aux langues d’Europe occidentale,

2. La dénominationANSI n’apparaît que dans la terminologie des produits Microsoften ré-férence au nom de l’institution nord-américaine de standardisation, bien que ce codage n’aitjamais été approuvé par cette dernière.

Page 414: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

422 Perl pour les linguistes

mais avec des valeurs numériques totalement différentes decelles de tous les autrescodages, comme indiquée dans la table A2.4. La liste des caractères définis parCP850est la suivante3 :

Ç ü é â ä à å ç ê ë è ï î ì Ä Å É æ Æ ô ö ò û ù ÿ Ö Ü ø£ Ø × f á í ó ú ñ Ñ ª º ¿ ® ¬ ½ ¼ ¡ « » Á  À © ¢ ¥ ã ä ð Ð Ê Ë È ı Í Î Ï ¦ Ì Ó ß Ô Ò õ Õ µ þ Þ Ú Û Ù ý Ý ¯ ´± ¾ ¶ § ÷ ¸ ° ¨ · 1 3 2

CommeCP1252, CP850contient un nombre de caractères plus important queLa-tin1 et Latin9. L’utilisation de ce codage est malheureusement très handicapante depar son incompatibilité majeure avectousles autres codes actuels. Nous renvoyons auparagraphe A2.3.1 sur la manière dont il est toutefois possible de le manipuler.

A2.2.6. MacRoman

Les systèmes d’exploitationMacOS, conçus par la société Apple, ont égalementleur propre histoire en ce qui concerne le codage des caractères latins. Leur systèmede codage, baptiséMacRomanest le codage par défaut sur les systèmes MacOS, ycompris la dernière génération (MacOs X). Sous cette version, toutefois, la plupartdes outils disponibles sont également capables de créer ou transformer des données enutilisant des codages de typeISO(Latin1et Latin9notamment).

La liste des caractères supplémentaires que définitMacRomanest la suivante :

Ä Å Ç É Ñ Ö Ü á à â ä ã å ç é è ê ¨ e í ì î ï ñ ó ò ô ö õú ù û ü † ° ¢ £ § • ¶ ß ® © ™ ´ ¨ 6= Æ Ø∞ ± ≤ ≥ ¥ µ ∂∑ ∏

π∫

ª º Ω æ ø ¿ ¡ ¬ √ f ≈ « » ... À Ã Õ Œ œ --- “ ” ‘ ’ ÷ ♦ ÿ Ÿ / C ‹ › fi fl ‡ · , „ ‰ Â Ê Á Ë È Í Î ÏÌ Ó Ô Ò Ú Û Ù ı ˆ ~ ¯ ˘ · ˚ ¸ ˝˛ ˇ

MacRomanest également en totale incompatibilité avec tous les autres codagesprésentés ici pour ce qui concerne les caractères accentués. Il contient, commeCP1252et CP850, plus de caractères que les codesLatin1etLatin9.

A2.2.7. Unicode

Le codage universel des caractères également baptiséUnicodecontient virtuel-lement des millions de caractères, dont nous ne donnons bienentendu pas la liste

3. Ce jeu de caractères contient également un grand nombre de caractères graphiques permettantde représenter des schémas. Nous ne les représentons pas ici, n’en retenant que les caractèreseffectivement rencontrés dans des textes.

Page 415: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Codage des caractères 423

ici. Chaque caractère y est repéré par un code, exprimé généralement en repré-sentation hexadécimale. La liste des caractères définis estdisponible sur le site :http://www.unicode.org/charts . Les caractères y sont réunis par familles,et les caractères latins y sont présents de façon exhaustiveen 6 familles de 256 carac-tères chacune.

Cette norme récente entraîne de nouvelles considérations sur les caractères et lecodage. Tout d’abord, il convient de prendre en compte la notion deformat, car plu-sieurs codages effectifs sont envisageables en se basant sur Unicode. Ensuite, il fautnoter que les caractères listés dans cette norme possèdent des propriétés explicites trèsutiles dans la manipulation de données linguistiques.

A2.2.7.1. FormatsUnicode: UTF-8, UTF-16, UTF-32

Le codageUnicode(également appelépoint de code) d’un caractère simple estexprimé par un code hexadécimal sur 4 chiffres (de 0000 à FFFF, ce qui couvre endécimal plus de 65 000 valeurs), utilisé dans les tables situées à la fin de ce chapitre.D’autres caractères supplémentaires sont, eux, codés sur 6chiffres (ce qui permetd’atteindre plus de 16 millions de valeurs), mais nous n’évoquons pas ici leur traite-ment. Ces caractères supplémentaires correspondent à des langues (très) anciennes ouinventées, ou encore à des versions alternatives des idéogrammes asiatiques.

Concrètement, ce type de codage ne peut pas se contenter de lacorrespondanceentre caractères et octets, puisque la capacité numérique d’un octet est de 256. Lasolution la plus directe consiste à utiliser trois octets pour chaque caractère (un octetpermettant de représenter 2 chiffres hexadécimaux), mais cela signifie alors qu’untexte en français, ainsi codé, a une taille trois fois plus importante que celle qu’il a avecun codage sur 8 bits. De plus, un tel codage est bien entendu incompatible avec tous lescodages préexistants, notamment le codeASCII sur lequel repose le fonctionnementde tous les systèmes informatiques actuels.

Pour résoudre ces deux problèmes, la normeUnicodes’accompagne deformats detransformation, dont le rôle est d’expliciter quelles valeurs numériques doivent êtreutilisées concrètement dans un fichier pour représenter un caractère.

Le formatUTF-32 (pour Unicode Transformation Format 32 bits) correspond àla méthode la plus simple, qui attribue à chaque caractère untotal de 4 octets. Cetteméthode est donc très peu économique.

Le formatUTF-8 (pourUnicode Transformation Format 8 bits) permet une netteéconomie par rapport àUTF-32, en représentant les caractères par un nombre d’octetsvariable, en fonction de leur famille. Plus particulièrement, ce format possède l’im-mense avantage d’être compatible avec le codeASCII (dont les caractères sont codésavec un seul octet). En ce qui concerne les caractères accentués utilisés pour le fran-çais, ceux-ci sont représentés par deux octets. Mais pour les caractères des langues

Page 416: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

424 Perl pour les linguistes

asiatiques, le formatUTF-8 utilise 4 octets : il est donc plus économique pour leslangues occidentales, et encore plus pour l’anglais.

Le formatUTF-16est intermédiaire entre les deux précédents, utilisant soit 2, soit4 octets en fonction des caractères. Il est donc incompatible avec le codeASCII.

Il n’existe donc pas de « codageUnicode» au sens des codages vus précédem-ment. Les formats décrits ici (UTF-8, UTF-16et UTF-32) doivent systématiquementêtre utilisés pour décrire le codage d’un fichier de texte.

A2.2.7.2. Propriétés des caractèresUnicode

L’établissement de la normeUnicodea également permis de définir des propriétésspécifiques à chaque caractère. Ces propriétés sont directement utilisables dans desprogrammes de manipulation de textes, et permettent une caractérisation fine des dif-férents types de caractères. Notamment, la normeUnicodedistingue les caractères quisont des lettres (avec distinction majuscule/minuscule),des signes de ponctuation, desséparateurs (espaces de tous types), des symboles, des chiffres, etc.

Les propriétés des caractèresUnicodesont utilisables en Perl dans le cadre desexpressions régulières, comme cela est indiqué dans le chapitre 4. Le tableau A2.4indique les principales propriétés associées à chacun d’eux. Ces propriétés sont utili-sables en Perl même si les données manipulées sont codées en utilisant un codage sur8 bits, puisqu’elles s’appliquent aux caractères eux-mêmes.

Il est enfin possible, pour certaines utilisations, de définir une propriété Unicodeen listant les caractères à laquelle elle s’applique. Le mécanisme est présenté en an-nexe A1 (paragraphe A1.2.2 page 399).

A2.2.7.3. Bilan pourUnicode

Malgré les difficultés liées à l’existence de différents formats, Unicode possède denombreux avantages sur tous les autres types de codage, de par son universalité. Parexemple, tous les codages précédents sur 8 bits peuvent êtrerecodés vers un codageUnicode, la réciproque n’étant bien entendu pas vraie dans le cas général.

La diffusion des formats Unicode est en croissance rapide, notammentvia dessupports comme le Web ou les normes de documents XML, et on trouve maintenantcouramment des ressources et des corpus du français codés enUTF-8.

L’un des points forts de cette norme est que les points de codeUnicode associés àchaque caractère peuvent être utilisés pour manipuler les caractères indépendammentdu codage. C’est le cas en Perl où la connaissance de ces codesnumériques garan-tit l’identification correcte du caractère quelles que soient les conditions de travail,comme indiqué en A2.5.

Page 417: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Codage des caractères 425

Par ailleurs, Unicode est également le codage de référence pour tout traitement dedonnées multilingues utilisant plusieurs alphabets.

Le lecteur intéressé par l’histoire d’Unicode et par les différents alphabets qui ysont représentés peut trouver toutes les informations pertinentes sur le site du consor-tium Unicode :

http://www.unicode.org

Dans l’ensemble de cet ouvrage, le seul format Unicode envisagé seraUTF-8. Tou-tefois, il est possible de passer d’un format Unicode à un autre sans aucune difficulté,en utilisant un utilitaire de recodage (voir A2.4.3).

A2.2.8. Codage enASCII des caractères non standards

Certains langages de formatage de texte ont également abordé le problème descaractères dépassant les limites du codeASCII, tout en utilisant ce codage. La solutionqu’ils adoptent est systématiquement de représenter un caractère nonASCII par uneséquence de caractèresASCII.

Ce dont il est question ici est la possibilité, pour un langage informatique, deciterun caractère pour qu’il soit ensuite reconnu, affiché, comparé, etc., sans pour autantle saisir directement. Nous retrouverons ce principe proche de celui de mention enlinguistique dans le langage Perl (voir section A2.5).

A2.2.8.1. XML

Le métalangage XML permet de représenter n’importe quel caractère en utilisantson point de codeUnicode. Les séquences utilisées sont du type&x####; , où les# correspondent au code hexadécimal tel qu’il est indiqué dans le tableau page 455.Ainsi, dans un fichier en XML, la séquence&x0153; permet d’indiquer une ligatureœ, indépendamment du codage utilisé dans le fichier. De telles séquences sont appe-léesentités, et sont traitées automatiquement par les outils de gestiondes données enXML (pour plus de détails, voir le chapitre 9). Cette possibilité n’est en aucun cas uneobligation, les caractères pouvant tout à fait être présents tels quels dans un fichierXML si le codage le permet.

A2.2.8.2. HTML

Le langage HTML fait partie de la même famille de métalangages qu’XML, et per-met lui aussi d’utiliser les entités exprimées par les codesnumériques. De plus, il per-met l’utilisation d’entités repérées par des noms pour un ensemble de caractères cou-rants, comme les lettres accentuées. Cela donne des séquences du type :&eacute;représente le caractère ‘é’. De telles séquences sont définies pour les principaux ca-ractères latins. Comme pour XML, cette possibilité s’ajoute à l’insertion normale decaractères accentués si le codage le permet. Pour plus de détails, voir le chapitre 10.

Page 418: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

426 Perl pour les linguistes

A2.2.8.3. TEX

Le processeur de texte TEX (et son extension LATEX) permet également de traiterdes caractères de tout type, tout en permettant la rédactionde document en codageASCII. Ces caractères nonASCIIsont exprimables par des séquences comme\’epour ‘é’, ainsi que certaines séquences prédéfinies comme\texteuro pour lesymbole de l’euro.

A2.2.8.4. Note

Les programmes de recodage permettent de manipuler ces types de représentationdes caractères (voir paragraphe A2.4.3).

A2.3. Liens entre codage et système d’exploitation

Comme on l’a vu dans la présentation des différents codages,la diversité des co-dages trouve son origine dans celle des programmes informatiques et des systèmesd’exploitation. Nous présentons donc dans cette partie lescaractéristiques de chaquefamille de système d’exploitation, en précisant les codages qu’ils considèrent commeétant par défaut, ainsi que les possibilités de travailler avec des codages différents.

A2.3.1. Windows (français)

Les codages de caractères disponibles sous un environnement Windows françaissont les suivants :

– CP850est le codage utilisé pour le français dans le système DOS, ancêtre deWindows. Toutefois,CP850reste le codage par défaut pour toute application Windowsfonctionnant en ligne de commande. Plus précisément, les caractères saisis au clavieret affichés à l’écran dans un terminal se fontvia ce codage. Les programmes Perllancés dans un tel environnement y sont donc assujettis ;

– CP1252est le codage par défaut utilisé par les autres applicationsWindows (édi-teurs de texte notamment). Rappelons que ce codage est également appelé «ANSI»dans la terminologie de Windows ;

– Unicode est utilisable par la plupart des applications récentes de manipulationde texte fonctionnant sous Windows, sous différents formats, dontUTF-8auquel nousnous intéresserons exclusivement. La plupart des éditeursde texte permettent de créer,visualiser et manipuler des textes codés enUTF-8, mais il s’agit rarement de leurcodage par défaut, qui resteCP1252.

La principale difficulté sous Windows vient de l’incompatibilité entreCP850etCP1252pour les lettres accentuées. Toutefois, il est désormais possible (sous Win-dows XP), d’utiliser dans un terminal le codageCP1252au lieu deCP850.

Page 419: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Codage des caractères 427

L’environnement de travail disponible sur le site Web compagnon inclut un rac-courci (sur le bureau) vers un terminal correctement configuré :PPLterm(voir 2.1.1).

Si l’on utilise le terminal par défaut de Windows, deux opérations sont nécessaires :

1) changer le codage: dans le terminal, taper la commande :chcp 1252 pourbasculer sur ce système de codage. Le changement est immédiat mais n’est valableque pour ce terminal ;

2) changer la police de caractères: dans les propriétés du terminal (accessiblespar un clic droit sur la barre de titre du terminal), sélectionner l’ongletPolice, puischoisir une police de caractères compatible avec le codageCP1252. La seule policedisponible par défaut est :Lucida Console.

Le retour au codageCP850se fait en tapant la commande :chcp 850 , puis enchoisissant la police intituléePolices Raster. Le codageCP850n’étant qu’un héritageencombrant du passé de cette famille de systèmes, il est rarede trouver des donnéesqui l’utilisent. De plus, son incompatibilité totale avec les autres codages modernes enfont un codage fortement déconseillé lorsque le choix est possible.

L’utilisation d’Unicode est également possible sous Windows, mais les caractèresautres que ceux du codeASCIIne sont pas visibles dans un terminal : leur visualisationdevra passer obligatoirement par une sortie dans un fichier texte, puis par l’utilisationd’un éditeur compatible avecUnicode.

A2.3.2. Unix

L’environnement Unix est généralement plus homogène du point de vue du codagedes caractères. Toutefois, sa plasticité implique que chaque système peut avoir unsystème de codage par défaut différent.

A l’heure actuelle, le codage par défaut des systèmes configurés en anglais ou enfrançais est généralement le codageLatin1, et plus rarementLatin9ouUTF-8.

Le codage par défaut se choisit généralementvia des variables d’environnementdévolues aux paramètres de localisation (voir annexe A3). Comme sous Windows, ilest également nécessaire d’adopter une police de caractères compatible avec le sys-tème de codage utilisé. Ainsi, il convient, lors d’un changement de codage dans unterminal, de modifier en même temps les paramètres des variables de localisation(voirannexe A3) et la police de caractères utilisée.

Nous ne détaillons pas l’ensemble des procédures de modification du codage dansun terminal Unix, puisqu’il existe plusieurs dizaines de tels outils. Nous invitons leslecteurs à consulter la documentation spécifique de leur terminaux.

Page 420: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

428 Perl pour les linguistes

A2.3.3. MacOS X

La dernière génération des systèmes MacOS de la firme Apple sesitue à la croiséeentre la situation d’Unix et celle de Windows. Historiquement, les anciens systèmeMacOS utilisaient le codageMacRoman, qui reste le codage par défaut pour un en-semble d’applications. La version X (sortie en 2001) inclutdésormais un noyau Unix,et permet de travailler sous cet environnement en utilisantles mêmes notions et lamême plasticité que pour cette famille de systèmes (notamment l’utilisation de diffé-rents terminaux, et les paramètres de localisation).

Nous recommandons vivement aux utilisateurs de ce système d’éviter d’utiliser lecodageMacRoman, qui est en incompatibilité totale avec les standards actuels (Latin1,Latin9, et mêmeCP1252).

A2.4. D’un code à l’autre

La multiplicité des codages disponibles étant souvent un obstacle à leur utilisa-tion, la première étape dans l’utilisation d’une ressourceest généralement un reco-dage, c’est-à-dire d’une transformation des données qui vont être manipulées par lasuite. Nous présentons ici en détail les possibilités de cestransformations, et les outilsdisponibles pour les effectuer.

A2.4.1. Diagnostics

Face à un fichier texte, la première chose à faire consiste à connaître son codage4.Il n’existe malheureusement pas de procédure de diagnosticautomatique fiable : tousles codages existants sont capables d’associer un caractère à une valeur numérique, etseule une compréhension humaine de la cohérence des donnéesainsi affichées permetde diagnostiquer un problème. Rappelons que la notion de codage n’est pas directe-ment liée à celle de langue, du moins pour un ensemble de langues partageant le mêmealphabet. Concrètement, il est souvent nécessaire d’essayer différents codages avantde trouver celui qui correspond à un fichier donné.

Les codages Unicode sont toutefois une exception à ce principe : comme ceux-cipeuvent utiliser plusieurs octets pour un caractère (et de ce fait utilisent des combi-naisons spécifiques de valeurs numériques), il est assez facile de les détecter. Certainséditeurs de texte le font d’ailleurs automatiquement ; pourles autres, tout comme pourles sorties de programmes à l’écran, le diagnostic se fait simplement sur l’apparition

4. Certains types de données contiennent cette information de façon explicite : c’est le cas desformats XML et HTML. Nous ne parlons ici que des formats de type texte brut.

Page 421: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Codage des caractères 429

ou la disparition de caractères. En effet, un fichier codé sur8 bits et interprété en Uni-code aboutit à la disparition de certains caractères (typiquement ceux situés avant ouaprès les caractères nonASCII). A l’inverse, un fichier Unicode interprété en codage8 bits fera apparaître des caractères excédentaires dans levoisinage des caractères nonASCII (les octets supplémentaires du codage Unicode étant interprétés par le codage8 bits).

Il est à noter enfin que les programmes les plus adéquats pour tester différentscodages sont les navigateurs Web (Firefox, Internet Explorer, etc.), puisque ceux-cisont les applications les plus couramment confrontées à la multiplicité des codagesprésents sur Internet. Il suffit pour cela d’ouvrir localement le fichier à diagnostiqueret de faire varier le codage utilisé par le navigateur pour l’interpréter (généralementdans le menuAffichage).

Le tableau A2.1 présente des situations classiques de confusion entre deux codagespour la phrase «Différentes façons de fâcher un bœuf». Il y est indiqué à la fois lecodage réel (c’est-à-dire du fichier contenant le texte) et celui utilisé pour afficher cesdonnées.

Codage Codage Résultatréel d’affichage

Latin1 CP1252 Différentes façons de fâcher un lapinLatin1 CP850 DiffÚrentes faþons de fÔcher un lapinLatin1 MacRomanDiffÈrentes faÀons de f,cher un lapin

Latin9 Latin1 Différentes façons de fâcher un b 1/2uf.Latin9 CP1252 Différentes façons de fâcher un b 1/2uf.Latin9 CP850 DiffÚrentes faþons de fÔcher un b¢uf.Latin9 MacRomanDiffÈrentes faÀons de f,cher un b ΩufCP850 Latin1/9 Diff rentes fa ons de f cher un lapin.CP850 CP1252 Diff,rentes fa‡ons de f fcher un lapin.CP850 MacRomanDiffÇrentes faáons de fÉcher un lapin.CP1252 Latin1/9 Différentes façons de fâcher un b uf.CP1252 CP850 DiffÚrentes faþons de fÔcher un b£uf.CP1252 MacRomanDiffÈrentes faÁons de f,cher un búuf.

MacRomanCP1252 Diff Zrentes fa ons de f‰cher un bÏuf.MacRomanCP850 DiffÄrentes faìons de fëcher un b uf.MacRomanLatin1/9 Diff rentes fa ons de f cher un bÏufCode 8 bitsUTF-8 Diff rentes fa ons de f cher un b uf.UTF-8 Latin 1/9 Différentes façons de fâcher un bÅ uf.UTF-8 CP1252 Différentes façons de fâcher un bÅ"uf.UTF-8 CP850 Diff |-®rentes fa |- oons de f |-ócher un b|-ôuf.UTF-8 MacRomanDiff

érentes fa

çons de f

âcher un b œuf.

Tableau A2.1.Situations classiques de codage inadapté

Page 422: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

430 Perl pour les linguistes

REMARQUE.– Pour certains cas, le motbœufa été remplacé parlapin, puisque laligatureœn’est pas possible enCP850ni enLatin1.

Le indique que le code du caractère original ne correspond pas àun caractèreaffichable dans le codage d’arrivée (pourLatin1 et Latin9), ou à une combinaisonillégitime pourUTF-8. Le résultat exact de l’affichage dépend alors de l’environne-ment de travail (éditeur, terminal, etc.). Dans certains cas, le caractère sera simplementinvisible, ou simulé par un code numérique, ou encore par un caractère générique (gé-néralement un point d’interrogation ou assimilé).

A2.4.2. Incompatibilités entre les codages

Les incompatibilités qui existent entre deux codages distincts sont de deux types :

– type A: les deux codages ne codent pas le même jeu de caractères ;

– type B: les deux codages assignent des codes différents aux mêmes caractères.

Le premier type d’incompatibilité (A) peut très bien n’exister que dans un sens.Par exemple, les codages Unicode sont compatibles avec tousles autres puisqu’ilscontiennent l’ensemble des caractères existants. Ainsi, il est possible de recoder den’importe quel codage versUTF-8sans perdre le moindre caractère (on peut le conce-voir comme un receveur universel). La réciproque est bien entendu fausse. A l’inverse,le codeASCII, sur lequel sont basés tous les codages existants, peut êtrerecodé versn’importe quel autre codage sans la moindre perte (c’est un donneur universel).

La situation est un peu plus complexe dans la réalité. Un fichier de texte codé enutilisant un codage donné n’utilise en fait qu’une partie des caractères disponibles.Ainsi, deux codes a priori incompatibles peuvent très bien l’être pour un fichier parti-culier. Ainsi, l’incompatibilité entreCP1252et Latin1ne s’applique pas si le texte necontient ni ligatures, ni euros, ni signes de ponctuation spécifiques.

L’incompatibilité de type B ne pose pas de problème difficileà résoudre, puisqu’ilsuffit de remplacer les codes des caractères en fonction des tables. C’est ce que fontles outils de recodage présentés au paragraphe A2.4.3.

Les incompatibilités entre les différents codages sont répertoriées dans le ta-bleau A2.2 (page 431), en se limitant aux seuls caractères utilisables pour un texte enfrançais. Y sont indiqués, pour les principaux couples de codages (initiaux et finaux)les caractères déplacés (donc mal représentés en l’absencede recodage) et manquants(ne pouvant être pris en compte dans le cas d’un recodage).Accentscorrespond à l’en-semble des lettres accentuées utilisées en français,ligaturesaux caractères œ et Œ, etponctuationà certains signes de ponctuation absents du codeASCII : apostrophe-guillemet, guillemets doubles, points de suspension, etc.Ces signes spécifiques sontnotamment présents dans les textes produits par les outils Windows. Nous revenonssur ce point au paragraphe A2.6.3.

Page 423: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Codage des caractères 431

Initial Final Déplacés Manquants

tous ASCII aucun accents, ligatures, ponctuation8 bits UTF-8 accents, ligatures, ponctuationaucunCP850 CP1252 accents, ponctuation aucunCP1252 CP850 accents, ponctuation ligaturesLatin1 CP1252 aucun aucunCP1252 Latin1 aucun ligatures, ponctuationLatin9 CP1252 ligatures aucunCP1252 Latin9 ligatures ponctuationLatin1 CP850 accents aucunCP850 Latin1 accents aucunMacRomanLatin1 accents ligatures, ponctuationLatin1 MacRomanaccents aucunMacRomanCP1252 accents, ponctuation aucunCP1252 MacRomanaccents, ponctuation aucun

Tableau A2.2. Incompatibilités entre les principaux codages

A2.4.3. Outils de recodage

L’opération de recodage permet de modifier le contenu d’un fichier en passant d’uncodage à un autre, en s’occupant des caractères déplacés dans le cas d’une incompati-bilité de type B.

Deux utilitaires sont disponibles pour modifier le codage d’un fichier : iconv etrecode. Le premier n’est disponible que sous Unix, tandis que le second est égalementdisponible sous Windows, par exemple dans la suite de programmesUnxUtils :

– iconv5 permet de produire un nouveau fichier codé différemment du fichiersource. Sa syntaxe est la suivante :

iconv -f <codage_source> -t <codage_cible> fichier

Le codage source doit correspondre à celui du fichier original, et le codage cibleest celui désiré. Les principaux codages présentés ici sontexprimables directementpar une chaîne de caractère, c’est-à-direlatin-1 , latin-9 , CP850, etc. Pourobtenir une liste complète des codages disponibles, lancezla commandeiconv -l(attention, la liste est très longue). Le contenu recodé estproduit en sortie standard,et peut être redirigé dans un nouveau fichier. En cas d’incompatibilité entre le fichiersource et le codage source, ou entre les deux codages (type A), un message d’erreursommaire est produit ;

5. http://www.gnu.org/software/libiconv/ .

Page 424: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

432 Perl pour les linguistes

– recode6 permet le même type d’opération qu’iconv, mais en modifiant directe-ment le fichier source. La syntaxe est légèrement différente:

recode <codage_source>..<codage_cible> fichier

Les contraintes et les codages utilisés sont similaires à ceux iconv (recode -lpermet d’avoir la liste des codes disponibles).

Il est possible, avecrecode, d’opérer un recodage vers un jeu de caractèresplus limité, avec comme résultat un remplacement des caractères incompatibles. Parexemple, le recodage deCP1252versLatin1d’un texte transformera les ligatures (œ)par une séquence de deux caractères (oe), et les apostrophes-guillemets vers des apos-trophes, etc.

De telles transformations peuvent toutefois poser des problèmes, d’autant qu’il estdifficile de les prévoir. Elles peuvent également être réalisées dans un programme Perl,et ainsi mieux contrôlées, comme indiqué au paragraphe A2.6.3.

Enfin, les outils de recodage sont également capables de modifier le codage desfins de lignes, dans le cas d’un fichier de texte provenant d’unsystème d’exploitationdifférent de celui sur lequel il va être utilisé. Suivant lescas, la séquence de fin deligne des systèmes Windows (CR-LF) sera produite, ou bien celle des systèmes Unix(LF). Le résultat de la transformation dépend du codage d’arrivée.

A2.5. Gestion des codages en Perl

REMARQUE.– Les techniques de gestion des codages en Perl ont rapidement évoluéavec les dernières version du langage. L’arrivée des codages Unicode a modifié pro-fondément les mécanismes internes de représentation des chaînes de caractères. Lesadaptations d’un programme Perl à un codage particulier quisont présentées danscette section se basent sur la version5.8du langage, et ne sont pas, pour la plupart, ac-cessibles dans les versions antérieures. Il est également possible qu’une future versionde Perl modifie à nouveau les fonctionnalités présentées.

Perl, en tant que langage de programmation dédié à la manipulation de donnéesde type texte, est doté de nombreuses fonctionnalités permettant de s’adapter à cetunivers complexe.

S’il est possible pour un programme simple d’ignorer l’ensemble des aspects tech-niques présentés ici, il arrive couramment qu’un programmeur soit confronté à dessituations nécessitant une adaptation d’un programme.

6. http://recode.progiciels-bpi.ca/ .

Page 425: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Codage des caractères 433

Cette section est consacrée à la façon dont Perl représente les chaînes de caractèresqu’il manipule, et à l’adaptation de son comportement à des codages particuliers quece soit en entrée, en sortie, ou en cours de traitement.

A2.5.1. Comportement par défaut : le codeLatin1

Perl considère par défaut que le codage utilisé est le standard Latin1. Cela signifieque l’interpréteur Perl considère que :

– le code source du programme est codé enLatin1;

– les données d’entrée sont codées enLatin1;

– l’utilisateur attend en sortie des données codées enLatin1.

Si toutes ces conditions sont remplies, le traitement se fait sans aucun problème.C’est la situation qui est considérée dans l’ensemble de l’ouvrage pour les pro-grammes présentés, à l’exception notable du traitement desdonnées issues du Web(chapitre 10) et des données au format XML (chapitre 9).

Dans cette situation standard, les propriétés Unicode des caractères sont utilisablespour les expressions régulières, puisque Perl a identifié correctement les caractèresqu’il manipule. De même, les opérations de tri respectent les règles de classementdes caractères accentués à condition que la commandeuse locale soit utilisée etque l’environnement du système d’exploitation soit compatible avec une localisationbasée sur le codeLatin1 (voir annexe A3).

Il arrive par exemple que l’environnement de travail utilise un codage proche deLatin1, mais distinct. Notamment, le codageCP1252(utilisé sous Windows) etLa-tin9 (très répandu sous Unix) ne se différencient deLatin1que sur quelques caractères(comme les ligatures œ, l’euroC et certains signes de ponctuation). Si ces caractèresne sont pas présents dans les données ni dans le code source duprogramme, le com-portement global sera conforme aux attentes.

La situation devient plus complexe dès lors qu’un des trois critères énoncés ci-dessus n’est pas respecté. En effet, si l’on force Perl à s’écarter de ce comportementpar défaut, la représentation des données manipulées se fait en utilisant le codageUTF-8. Le choix de ce codage est justifié par son statut de nouveau standard et par sacapacité à représenter l’ensemble des caractères existants.

A2.5.2. Notation des autres caractères dans le code Perl :\x####

Dans la plupart des cas, le code source du programme Perl ne pose en réalité aucunproblème, puisqu’a priori les seuls caractères nécessaires sont les caractères du code

Page 426: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

434 Perl pour les linguistes

ASCII. Toutefois, il est courant que l’on ait à y évoquer des caractères plus exotiquesdans des chaînes de caractères constantes ou des expressions régulières : dans ce casse pose la question de la notation de ces caractères.

Les caractères en question peuvent être simplement difficiles à saisir au clavier,tout en faisant partie du jeu de caractères deLatin1 (par exemple des lettres ou signesde ponctuation utilisés par une autre langue que le français, comme leß de l’allemandou le ¡ de l’espagnol). Ils peuvent également faire partie d’autres jeux de caractères,comme le symbole de l’euro, voire des caractères d’autres alphabets.

Dans les deux cas, la solution consiste à utiliser une notation faisant appel aupoint de code Unicode des caractères en question. Nous donnons dans le tableau A2.4(page 451) la liste des codes Unicode des principaux caractères utilisés pour le fran-çais à travers les codages dont nous parlons. Cette notationidentifie le caractère defaçon absolue, et peut être utilisée indépendamment du codage des données en entréeou en sortie.

Tout caractère peut s’exprimer en Perl de la façon suivante :\x#### où les#correspondent au point de code Unicode (en hexadécimal) du caractère. Par exemple,le caractère correspondant au point d’exclamation inversé(¡) a pour point de codeUnicode le numéro 00A1. On le notera alors\x00A1 .

Cette notation peut être utilisée dans toute chaîne constante utilisant des guillemetsdoubles, ainsi que dans tout expression régulière.

Toutefois, dans le cas où le caractère ainsi évoqué ne fait pas partie deLatin1, il estnécessaire d’indiquer dans le programme Perl qu’un autre codage doit être utilisé pourles données de sortie. Sans cela, un message d’erreur sera produit car le caractère enquestion ne peut être affiché correctement. Ce point fait l’objet du paragraphe suivant.

A2.5.3. Codage des données d’entrée et de sortie : la fonction binmode

Si les données d’entrée ou de sortie du programme ne sont pas codées enLatin1, ilest nécessaire d’indiquer cet état de fait au programme Perl. La méthode d’adaptationest la même dans les deux situations, mais les conséquences en sont distinctes.

A2.5.3.1. Données d’entrée

Pour qu’un programme Perl puisse traiter correctement des données d’entrée co-dées à l’aide d’un autre codage queLatin1, il est nécessaire d’indiquer, pour chaquedescripteur (de fichier ouvert en lecture ou du flux d’entrée standard STDIN) le co-dage à utiliser pour lire les données. Ceci se fait à l’aide dela fonctionbinmodede lafaçon suivante :

binmode( DESCRIPTEUR, ":encoding( codage )" );

Page 427: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Codage des caractères 435

Cette commande doit précéder toute opération de lecture surle descripteur en ques-tion. Par exemple, pour indiquer que les données qui vont être lues par un programmesur l’entrée standard sont codées enLatin9, il est nécessaire de placer en début deprogramme :

binmode( STDIN, ":encoding(latin9)" );

Pour lire le contenu du fichierexemple-cp1252.txt en indiquant qu’ilcontient du texte codé enCP1252, il suffit d’utiliser le code suivant :

open( IN, "<", "exemple-cp1252.txt" ) or die "...";binmode( IN, ":encoding(cp1252)" );while ( my $ligne = <IN> ) ...

Perl est relativement souple pour l’écriture du nom des codages. Par exemple,latin9 , latin-9 , iso-8859-15 sont tous synonymes. Il est nécessaire de ré-péter cette opération pour chaque descripteur de fichier ; ilest bien entendu possiblede manipuler dans un même programme des fichiers utilisant des codages différents.

Une fois la lecture effectuée, il est possible de manipuler les données indépendam-ment de leur codage initial. Si l’on souhaite manipuler des caractères qui ne font paspartie du codageLatin1, il suffit de citer ceux-ci en utilisant la notation\x####vue précédemment. Par contre, de tels caractères ne pourront pas être affichés correc-tement si le codage des données de sortie n’est pas lui aussi modifié.

A2.5.3.2. Données de sortie

La fonctionbinmode peut s’appliquer avec la même syntaxe que précédemmentau descripteur de la sortie standard (STDOUT) ou d’un fichierouvert en écriture.

Dans ce cas, toute chaîne de caractère écrite sera automatiquement recodée enutilisant le codage indiqué.

Ainsi, pour que la sortie standard d’un programme se fasse encodageUTF-8, ilsuffit d’indiquer dans le programme (avant toute opération d’écriture) :

binmode( STDOUT, ":encoding(utf8)" );

Il est ainsi possible d’utiliser des codages différents en entrée et en sortie d’unprogramme (et ainsi de construire à peu de frais un programmede recodage).

Toutefois, si les caractères écrits ne sont pas compatiblesavec le codage de sortie,un message d’erreur indiquera, au moment de l’écriture, queceux-ci ne seront pascorrectement représentés.

Page 428: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

436 Perl pour les linguistes

Ce message d’erreur est :Wide character in print at xxx.pl line yy.

Son apparition ne stoppe pas l’exécution du programme, maisest une indicationfiable d’une sortie incorrecte. Plus précisément, le caractère problématique sera repré-senté en traduisant son codageUTF-8 dans le codage de sortie. Le résultat obtenu aufinal est donc similaire à celui obtenu dans les lignes du tableau A2.1 pour un codageUTF-8.

Il existe deux façons de résoudre ce problème :

1) modifier le codage de sortie pour utiliser un codage compatible avec ce carac-tère (par exemple, utiliser une sortie enLatin9 pour permettre l’affichage correct duœ) ;

2) traiter spécifiquement le caractère en question, c’est-à-dire le remplacer par unautre (ou une série d’autres) qui soit compatible avec le codage utilisé en sortie. Parexemple, remplacer le caractèreœpar la séquenceoe.

A2.5.4. Exemples complets

Pour résumer les différentes possibilités offertes, voiciun programmeextrait-oe.plfonctionnant dans la situation suivante :

– environnement de travail : Windows ;

– entrée : texte brut enLatin9 (fichier texte-latin9.txt) contenant la ligne de texte :Un bœuf ne pond pas d’œufs. ;

– objectif : extraction des mots contenant des ligatures œ ouŒ ;

– sortie : sortie standard enCP1252.

Listing A2.1 – extrait-oe.plExtraction de ligatures codées enLatin9sous Windows avec sortie enCP1252

1 use locale;2 use strict;3 open ( IN, "<", "texte-latin9.txt" ) or4 die "Problème d’ouverture du fichier : ", $!, "\n";5 binmode ( IN, ":encoding(latin9)" );6 binmode ( STDOUT, ":encoding(cp1252)" );7

8 while ( my $ligne = <IN> )9 chomp $ligne;

10 while ( $ligne=~ /(\pL * [\x0152\x0153]\pL * )/g )11 print $1, "\n";12 13 14 close IN;

Page 429: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Codage des caractères 437

Ligne de commande :perl extrait-oe.pl

Résultat :bœufœufs

COMMENTAIRES.– Le fichier d’entrée est explicité comme étant codé enLatin9 parla fonctionbinmode, immédiatement après son ouverture (lignes 3 et 4) :

– la sortie standard est explicitement codée enCP1252par la même méthode(ligne 5) ;

– les caractères œ et Œ sont exprimés dans l’expression régulière en utilisant leurpoint de codeUnicode: \x0152 et \x0153 ;

– aucun traitement spécifique des caractères n’est à prévoir, puisque tous les ca-ractères deLatin9sont représentés enCP1252.

La sortie étant codée enCP1252, elle n’est correctement visible dans le termi-nal Windows que si celui-ci est correctement configuré commeindiqué au para-graphe A2.3.1 en utilisant la commande systèmechcp 1252 et utilisant la policede caractèresLucida Console. Si la sortie est redirigée vers un fichier texte qui estensuite ouvert avec un éditeur Windows (notamment le bloc-notes) les ligatures et lesaccents seront correctement affichés.

Si l’on souhaitait que le résultat apparaisse enCP850(c’est-à-dire le codage pardéfaut des terminaux sous Windows), le programme devrait être modifié pour obtenirla version présentée dans le listing A2.2.

Listing A2.2 – extrait-oe-CP850.plExtraction de ligatures codées enLatin9sous Windows avec sortie enCP850

1 use locale;2 use strict;3 open ( IN, "<", "texte-latin9.txt" ) or4 die "Problème ouverture de fichier : ", $!, "\n";5 binmode ( IN, ":encoding(latin9)" );6 binmode ( STDOUT, ":encoding(cp850)" );7

8 while ( my $ligne = <IN> )9 chomp $ligne;

10 while ( $ligne=~ /(\pL * [\x0152\x0153]\pL * )/g )11 my $mot = $1;12 $mot =~s /\x0152/OE/g;13 $mot =~s /\x0153/oe/g;14 print $mot, "\n";15 16 17 close IN;

Page 430: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

438 Perl pour les linguistes

Ligne de commande :perl extrait-oe-CP850.pl

Résultat :boeufoeufs

Le codageCP850est utilisé pour coder la sortie du programme à la place deCP1252. Dans ce cas, puisque les ligatures ne font pas partie du jeu de caractèresCP850, un remplacement par la séquenceoe ou OE est nécessaire. C’est ce qui estfait en lignes 11 et 12.

A2.5.5. Recodage interne en Perl : le moduleEncode

Dans certaines situations précises, notamment lorsqu’un programme Perl fait ap-pel à des modules externes de manipulation de données, il arrive que certaines donnéessoient obtenues dans un codage autre queLatin1. Par exemple, les modules permet-tant de manipuler du XML en Perl produisent systématiquement des données codéesen UTF-8, et attendent également des données dans un tel codage pour produire undocument. Les modules permettant le téléchargement de pages Web doivent s’adapterdynamiquement au codage utilisé pour chaque page. Dans ces cas spécifiques, il estnécessaire, pour manipuler correctement ces données, de les recoder en interne dans leprogramme, puisqu’il n’est pas possible d’adapter directement les opérations d’entréeet de sortie parbinmode.

Le module standardEncode permet d’effectuer ces transformations de façon re-lativement simple. On fait appel à ce module en utilisant la ligne :

use Encode;

en début de code.

Ce module dispose de deux fonctions principales :

– decode( codage , chaîne ) qui permet de construire une représentation in-terne de la chaîne passée en paramètre si celle-ci est codée dans le codage indiqué. Parexemple, si$chaine contient une chaîne de caractères codée enCP1252, après lacommande :

$chaine = decode( "cp1252", $chaine_1252 );

la variable$chaine contiendra la représentation interne correcte du contenu de$chaine_1252 ;

– encode( codage , chaîne ) effectue le travail inverse dedecode, et permetde passer d’une représentation interne à une chaîne codée dans le codage indiqué.Ainsi, la commande suivante :

Page 431: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Codage des caractères 439

$chaine_latin1 = encode( "latin1", $chaine );

effectuée à la suite de la commande précédente, construit etstocke dans la variable$chaine_latin1 une version codée enLatin1de$chaine .

Ces deux fonctions ne sont utiles que si le programme Perl où elles apparaissentest confronté à des situations complexes comme celles évoquées ci-dessus. Dans latrès grande majorité des cas, les conversions de codage sonteffectuées uniquement aumoment des entrées et sorties en utilisant l’instructionbinmode.

A2.6. Problèmes fréquents

A2.6.1. Sous Windows, la sortie d’un programme dans un terminal n’affiche pascorrectement les caractères accentués

Comme indiqué au paragraphe A2.3.1, le terminal de Windows utilise par défautle codageCP850, alors qu’un programme Perl utilise par défaut le codageLatin1.

Pour résoudre ce problème, il faut soit modifier le codage du terminal, soit celuidu programme (c’est-à-dire ses codages d’entrée et de sortie). La première solution(fortement conseillée) est indiquée en A2.3.1.

La seconde, qui implique que le programme ainsi créé ne fonctionnera correcte-ment que dans ce type d’environnement, consiste à appliquerla fonctionbinmodepour fixer le codage des entrées et sorties àCP850.

A2.6.2. L’exécution d’un programme donne le message d’erreur :Wide characterin print...

Le message d’erreurWide character in print at xxx.pl line yyest une indicationpar l’interpréteur Perl qu’un caractère a voulu être affichéalors qu’il ne fait pas par-tie du codage utilisé en sortie (comme le caractèreœpour Latin1). Cette situationn’empêche pas l’exécution du programme, mais le caractère en question est affiché defaçon incorrecte dans les données de sortie. La résolution de ce problème est indiquéeen A2.5.3.

A2.6.3. Sous Unix, l’utilisation de données provenant de Windows pose des pro-blèmes

Comme indiqué en A2.2.4, le jeu de caractères par défaut sousWindows pour leslangues occidentales (CP1252) est plus étendu queLatin1. Plus particulièrement, ilcontient certains signes de ponctuation comme les guillemets-apostrophes (’ et ‘ ),

Page 432: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

440 Perl pour les linguistes

les tirets cadratins et demi-cadratins (— et –), ainsi que les ligatures (œ et Œ) et lesymbole de l’euro. Le problème le plus courant provient est celui du guillemet an-glais simple droit (‘ ) qui est utilisé comme apostrophe courbe dans les logicielsdebureautique de Microsoft.

Un texte rédigé en utilisant un traitement de texte sous Windows a de grandesprobabilités7de ne contenir aucune apostrophe classique (c’est-à-dire le caractère’ ducodeASCII). Cette situation est également présente pour certaines pages Web saisiesavec les mêmes outils.

Ces caractères supplémentaires, bien que représentant lesnormes pointues de latypographie française, ne sont pas adaptés à un traitement des données textuelles. Enpremier lieu, ils ne sont pas accessibles directement sur les claviers français (la touchede l’apostrophe renvoyant une apostrophe classique), et nesont donc pas accessibledans un éditeur de texte. En second lieu, ne faisant pas partie du codageLatin1, bonnombre de logiciels de manipulation de textes, dont le langage Perl, ne les prennentpas en compte sans une adaptation spécifique à la charge de leur utilisateur.

Le tableau suivant répertorie ces caractères en rappelant leur code Unicode :

Caractère Point de code UnicodeDescription... 2026 points de suspension

‘ 2018 guillemet-apostrophe culbuté’ 2019 guillemet-apostrophe– 2013 tiret demi-cadratin— 2014 tiret cadratin“ 201C guillemet-apostrophe double culbuté” 201D guillemet-apostrophe double

Leur détection en tant que caractères manipulables par un programme Perl se faitdans une des situations suivantes :

– ils sont présents dans un texte codé enCP1252: il convient alors de le signalerà Perl lors de la lecture des données, par exemple en utilisant la commande :

binmode( DESCRIPTEUR, ":encoding(cp1252)" );

– ils sont obtenus par un appel à un module de manipulation de données externes,comme les modules de manipulation des pages Web ou les analyseurs XML.

7. Les logiciels de la suite Microsoft Office ont ce comportement par défaut. Bien qu’une op-tion permette de contrôler l’insertion automatique de ces caractères, de nombreux textes élec-troniques disponibles sur le Web contiennent des caractères spécifiques à cause de ces outils.

Page 433: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Codage des caractères 441

Pour le traitement de ces données à proprement parler (par exemple pour segmen-ter la chaîne, ou repérer des séquences de caractères contenant une telle apostrophe),deux solutions sont envisageables :

– si l’on souhaite respecter ces caractères particuliers aulong du traitement et ensortie, il est nécessaire pour les manipuler d’utiliser leurs points de codeUnicode, parexemple :\x2019 pour le guillemet-apostrophe. Dans ce cas également, la sortiedoit bien entendu être produite enCP1252ou enUTF-8, seuls codages compatiblesavec ces caractères ;

– si l’on souhaite simplement considérer ces caractères comme les caractères clas-siques correspondants, le plus simple est de les remplacer,en appliquant par exemplela fonction suivante sur chaque chaîne susceptible d’en contenir :

sub normalise_latin1

my $chaine = shift @_;

$chaine =~ s/[\x2019\x2018]/\’/g;

$chaine =~ s/[\x201C\x201D]/\"/g;

$chaine =~ s/[\x2013\x2014]/-/g;

$chaine =~ s/\x2026/.../g;

$chaine =~ s/\x0152/OE/g;

$chaine =~ s/\x0153/oe/g;

$chaine =~ s/[^\x0000-\x00FF]//g;

return $chaine;

A2.6.4. Le tri lexicographique ne se fait pas correctement pour les lettres accen-tuées

Les opérations de comparaisons des chaînes de caractères suivant l’ordre lexico-graphique (et notamment le tri de chaînes par ordre) peut poser des problèmes lorsqueles données contiennent des lettres accentuées. Par défaut, l’ordre des caractères estcelui de leur valeur numérique dans le codageLatin1. L’utilisation deslocalespermetd’adapter ce comportement en positionnant les lettres accentuées au même niveau queleur correspondant non accentué (c’est-à-dire en positionnant leé au même niveauque lee). L’instructionuse locale; en début de code permet d’activer cette adap-tation, comme indiqué en annexe A3. Le comportement est toutà fait correct dans lecas où les données sont codées enLatin1ou dans un codage similaire sur 8 bits, si lesvariableslocalessont correctement positionnées.

Toutefois, certaines situations peuvent conduire à un comportement erroné, malgrécette fonctionnalité. Ce type de problème est assez difficile à gérer en Perl, puisqueles localeset la gestion des codages de caractères utilisent des concepts d’originesdistinctes dans l’histoire du développement du langage Perl.

Page 434: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

442 Perl pour les linguistes

La situation la plus problématique est celle où les données sont obtenuesvia desfonctions spécifiques à certains modules, et notamment celles qui permettent de ma-nipuler des données au format XML. Dans ce cas, comme indiquéau chapitre 9, leschaînes de caractères obtenues sont systématiquement codées enUTF-8, même si lecodage du fichier estLatin1. Les paramètres de localisation doivent alors indiquer queles comparaisons lexicographiques doivent se baser sur le codageUTF-8, en affectantpar exemple la valeurfr_FR.UTF8 aux variables de localisation. Le détails de ceparamétrage est indiqué en annexe A3. Cette possibilité n’existe toutefois pas pourles systèmes Windows, pour lesquels les paramètres de localisation sont limités à descodages 8 bits.

Une autre solution (valable pour tous les systèmes) consiste à utiliser le moduleEncode comme indiqué en A2.5.5 pour convertir de façon interne les données enLatin1, par la commande suivante :

$chaine = encode ("latin1", $chaine);

Une fois cette conversion faite, les comparaisons lexicographiques peuvent se faireen utilisant une localisation basée surLatin1.

A2.6.5. Sous Unix, comment travailler en environnement Unicode ?

Bien que Perl soit avant tout conçu pour fonctionner en environnementLatin1, ilest tout à fait possible de faire fonctionner des programmesdans un environnementen Unicode, ou plus précisément enUTF-8 sous Unix. Cela signifie que les donnéesd’entrée saisies au clavier (via l’entrée standard non redirigée) sont codées enUTF-8,que les données affichées dans le terminal (via l’entrée standard non redirigée ou lecanal d’erreur standard) seront interprétées enUTF-8, et que les éventuels argumentspassés au programme sont également codées enUTF-8.

Il existe un moyen simple d’exécuter un programme Perl en adaptant les codagesde ces différents canaux de communication. Il suffit d’appliquer l’option-C de l’in-terpréteur Perl, en lui appliquant la valeurSA. Ainsi, la ligne de commande à utiliserpour lancer le programmeX.pl sous un environnementUTF-8est la suivante :

perl -CSA X.pl

Cette possibilité suffit généralement dans la plupart des programmes simples.

Pour les cas où les entrées ou sorties standard sont redirigées, l’option ci-dessusimplique que les fichiers servant à la redirection sont codésenUTF-8. Par contre, lesfichiers ouverts directement par le programme (via la fonctionopen) seront manipulésavec le codage par défaut, doncLatin1 : il est nécessaire de leur appliquer la fonctionbinmode si leur contenu est également enUTF-8.

Page 435: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Codage des caractères 443

A2.7. Références des principaux codages

Cette section contient les tables de références des codagesde caractères évoquésplus haut, et permettent d’accéder rapidement aux informations concernant un carac-tère donné.

A2.7.1. Liste des caractères non affichables

Les caractères non affichables sont communs à tous les codes existants, del’ ASCIIà Unicode. La liste complète est donnée pour information dans la tableA2.3(page 444). Ces caractères ont pour but d’organiser l’information dans un processusde communication, mais certains ont un intérêt pour le traitement des données linguis-tiques, et sont indiqués en gras.

Pour chaque caractère sont indiqués son nom abrégé (code de deux ou trois lettrescorrespondant à un terme en anglais), son nom en français (suivant le standard detraductionISO 6429), son code décimal enASCII et dans tous les autres codagestraités dans cette annexe, ainsi que son code Unicode en hexadécimal.

Les principaux caractères à considérer sont :

– la tabulation horizontale, ou simplementtabulation est couramment utiliséecomme séparateur dans les formats de fichiers annotés. Lorsqu’elle est insérée dansun texte, elle est affichées comme un espacement horizontal dont la taille varie de 1 à8 caractères affichables. La taille exacte dépend en fait de la position de ce caractèresur la ligne, puisque le rôle de la tabulation est d’aligner la partie de texte située aprèselle sur le prochaintaquet de tabulation. Les taquets sont traditionnellement placéstous les 8 caractères. L’intérêt majeur de ce caractère est qu’il reste visible tout enne faisant normalement pas partie des caractères rencontrés dans un texte : il peutainsi être utilisé comme séparateur non ambigu de différentes chaînes de caractères(par exemple une entrée de lexique et son étiquette catégorielle, etc.) La tabulation estnotée\t en Perl ;

– le passage à la ligne(ou line feed, noté également LF) est le caractère de fin deligne sous les systèmes Unix ;

– le retour chariot(ou carriage return, noté également CR) sert, sous Windows,s’il est suivi d’un passage à la ligne, à coder une fin de ligne ;

– le caractère d’espace est souvent considéré comme un caractère non affichable,mais sa manipulation ne pose bien entendu pas de problème.

Dans certains contextes, les caractères non affichables éventuellement présentsdans un fichier seront tout de même représentés. Leur apparence sera alors décidéepar l’éditeur utilisé pour les visualiser. Dans certains cas, il s’agira d’un caractère

Page 436: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

444 Perl pour les linguistes

générique comme, dans d’autre le code numérique assorti d’une mise en forme par-ticulière, et dans d’autres cas encore une notation du type^X où X est une lettremajuscule dont le rang dans l’alphabet correspond au code ducaractère en question.Ainsi, avec cette dernière représentation, le caractère « Sonnerie » dont le code est 07sera représenté par^G (G étant la 7e lettre de l’alphabet).

Il est également possible d’entrer ces caractères au clavier en utilisant la mêmeassociation entre nombres et lettres. Les combinaisons de touches CTRL et une lettre

Nom Signification CodeASCII Point de codeUnicode

NUL Nul 0 0000SOH Début d’entête 1 0001STX Début de texte 2 0002ETX Fin de texte 3 0003EOT Fin de transmission 4 0004ENQ Demande 5 0005ACK Accusé de réception 6 0006BEL Sonnerie 7 0007BS Espace arrière 8 0008

TAB Tabulation horizontale 9 0009LF Passage à la ligne 10 000AVT Tabulation verticale 11 000BFF Saut de page 12 000CCR Retour de chariot 13 000DSO Hors code 14 000ESI En code 15 000F

DLE Echappement de transmission 16 0010DC1 Contrôle de dispositif 1 17 0011DC2 Contrôle de dispositif 2 18 0012DC3 Contrôle de dispositif 3 19 0013DC4 Contrôle de dispositif 4 20 0014NAK Accusé de réception négatif 21 0015SYN Synchronisation 22 0016ETB Fin de bloc de transmission 23 0017CAN Annulation 24 0018EM Fin de support 25 0019

SUB Substitution 26 001AESC Echappement 27 001BFS Séparateur de fichier 28 001CGS Séparateur de groupe 29 001DRS Séparateur d’enregistrement 30 001EUS Séparateur d’enregistrement 31 001FSP Espace 32 0020

DEL Suppression 128 00FF

Tableau A2.3.Caractères non affichables des codesASCII et ISO

Page 437: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Codage des caractères 445

servent généralement à exprimer le caractère dont le code est égal au numéro d’ordrede la lettre dans l’alphabet. C’est ainsi que certains caractères non affichables sont enfait vitaux dans les environnements informatiques, notamment la séquence CTRL-D(correspondant au caractère « fin de transmission ») indiquant la fin d’un flux de don-nées entrée au clavier. De même, taper CTRL-J a, sous Unix, les mêmes conséquencesque de taper la touche « Entrée », de même que CTRL-H et la touche d’effacement,etc.

A2.7.2. Tables des principaux caractères latins à travers les codages les plusfréquents

Le tableau A2.4 (page 446) présente les principaux caractères latins apparaissantdans les différents codes évoqués :Latin1, Latin9, CP850, CP1252, MacRomanainsique son codageUnicode(en hexadécimal). Enfin, sont indiquées les principales pro-priétés de chaque caractère :

– les signes de ponctuation sont indiqués par la lettreP ;

– les lettres minuscules parLl ;

– les majuscules parLu ;

– les symboles parS ;

– les nombres parN;

– les séparateurs parZ ;

– les caractères de contrôle parC.

Cette notation correspond aux classes prédéfinies directement utilisables dans lesexpressions régulières de Perlvia la syntaxe\pX (ou \pXX si la propriété estdéfinie par plusieurs lettres), voir chapitre 4.

Le tableau A2.5 (page 452) présente les informations permettant d’identifier lesproblèmes d’incompatibilité de codage en listant les caractères de chacun des codes 8bits par valeur numérique.

REMARQUE.– Les caractères indiqués par sont soit des caractères non affichables,soit des caractères graphiques inusités dans les données linguistiques.

Le symbole n° 173 des codesLatin1, Latin9etCP1252correspond au trait d’unionvirtuel utilisé notamment pour indiquer les césures possibles dans un mot. Il est doncnon affichable.

Page 438: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

446 Perl pour les linguistes

Caractères du codeASCII (1)Car. Latin1 Latin9 CP850CP1252MacRomanUnicodePropriétés

! 33 33 33 33 33 0021 P" 34 34 34 34 34 0022 P# 35 35 35 35 35 0023 P$ 36 36 36 36 36 0024 S% 37 37 37 37 37 0025 P& 38 38 38 38 38 0026 P’ 39 39 39 39 39 0027 P( 40 40 40 40 40 0028 P) 41 41 41 41 41 0029 P

* 42 42 42 42 42 002A P+ 43 43 43 43 43 002B S, 44 44 44 44 44 002C P- 45 45 45 45 45 002D P. 46 46 46 46 46 002E P/ 47 47 47 47 47 002F P0 48 48 48 48 48 0030 N1 49 49 49 49 49 0031 N2 50 50 50 50 50 0032 N3 51 51 51 51 51 0033 N4 52 52 52 52 52 0034 N5 53 53 53 53 53 0035 N6 54 54 54 54 54 0036 N7 55 55 55 55 55 0037 N8 56 56 56 56 56 0038 N9 57 57 57 57 57 0039 N: 58 58 58 58 58 003A P; 59 59 59 59 59 003B P< 60 60 60 60 60 003C S= 61 61 61 61 61 003D S> 62 62 62 62 62 003E S? 63 63 63 63 63 003F P@ 64 64 64 64 64 0040 PA 65 65 65 65 65 0041 LuB 66 66 66 66 66 0042 LuC 67 67 67 67 67 0043 LuD 68 68 68 68 68 0044 LuE 69 69 69 69 69 0045 LuF 70 70 70 70 70 0046 LuG 71 71 71 71 71 0047 Lu

Page 439: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Codage des caractères 447

Caractères du codeASCII (2)Car. Latin1 Latin9 CP850CP1252MacRomanUnicodePropriétés

H 72 72 72 72 72 0048 LuI 73 73 73 73 73 0049 LuJ 74 74 74 74 74 004A LuK 75 75 75 75 75 004B LuL 76 76 76 76 76 004C LuM 77 77 77 77 77 004D LuN 78 78 78 78 78 004E LuO 79 79 79 79 79 004F LuP 80 80 80 80 80 0050 LuQ 81 81 81 81 81 0051 LuR 82 82 82 82 82 0052 LuS 83 83 83 83 83 0053 LuT 84 84 84 84 84 0054 LuU 85 85 85 85 85 0055 LuV 86 86 86 86 86 0056 LuW 87 87 87 87 87 0057 LuX 88 88 88 88 88 0058 LuY 89 89 89 89 89 0059 LuZ 90 90 90 90 90 005A Lu[ 91 91 91 91 91 005B P\ 92 92 92 92 92 005C P] 93 93 93 93 93 005D Pˆ 94 94 94 94 94 005E S_ 95 95 95 95 95 005F P‘ 96 96 96 96 96 0060 Sa 97 97 97 97 97 0061 Llb 98 98 98 98 98 0062 Llc 99 99 99 99 99 0063 Lld 100 100 100 100 100 0064 Lle 101 101 101 101 101 0065 Llf 102 102 102 102 102 0066 Llg 103 103 103 103 103 0067 Llh 104 104 104 104 104 0068 Lli 105 105 105 105 105 0069 Llj 106 106 106 106 106 006A Llk 107 107 107 107 107 006B Lll 108 108 108 108 108 006C Llm 109 109 109 109 109 006D Lln 110 110 110 110 110 006E Llo 111 111 111 111 111 006F Ll

Page 440: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

448 Perl pour les linguistes

Caractères du codeASCII (3)Car. Latin1 Latin9 CP850CP1252MacRomanUnicodePropriétés

p 112 112 112 112 112 0070 Llq 113 113 113 113 113 0071 Llr 114 114 114 114 114 0072 Lls 115 115 115 115 115 0073 Llt 116 116 116 116 116 0074 Llu 117 117 117 117 117 0075 Llv 118 118 118 118 118 0076 Llw 119 119 119 119 119 0077 Llx 120 120 120 120 120 0078 Lly 121 121 121 121 121 0079 Llz 122 122 122 122 122 007A Ll 123 123 123 123 123 007B P| 124 124 124 124 124 007C S 125 125 125 125 125 007D P˜ 126 126 126 126 126 007E S

Extensions : signes de ponctuationCar. Latin1 Latin9 CP850CP1252MacRomanUnicodePropriétés

... - - - 133 201 2026 P› - - - 155 221 203A P- - - - 150 208 2013 P‹ - - - 139 220 2039 P” - - - 148 211 201D P‰ - - - 137 228 2030 P“ - - - 147 210 201C P‘ - - - 146 213 2019 P• - - - 149 165 2022 P

-- - - - 151 209 2014 P† - - - 134 160 2020 P„ - - - 132 227 201E P‡ - - - 135 224 2021 P¡ 161 161 173 161 193 00A1 P« 171 171 174 171 199 00AB P· 183 183 250 183 225 00B7 P» 187 187 175 187 200 00BB P¿ 191 191 168 191 192 00BF P- 173 173 240 173 - 00AD C

Page 441: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Codage des caractères 449

Extensions : NombresCar. Latin1 Latin9 CP850CP1252MacRomanUnicodePropriétés

2 178 178 253 178 - 00B2 N3 179 179 252 179 - 00B3 N1 185 185 251 185 - 00B9 N¼ 188 - 172 188 - 00BC N½ 189 - 171 189 - 00BD N¾ 190 - 243 190 - 00BE N

Extensions : SymbolesCar. Latin1 Latin9 CP850CP1252MacRomanUnicodePropriétés

~ - - - 152 247 02DC SC - 164 - 128 219 20AC S™ - - - 153 170 2122 S¢ 162 162 189 162 162 00A2 S£ 163 163 156 163 163 00A3 S¤ 164 - 207 164 - 00A4 S¥ 165 165 190 165 180 00A5 S¦ 166 - 221 166 - 00A6 S§ 167 167 245 167 164 00A7 S¨ 168 - 249 168 172 00A8 S© 169 169 184 169 169 00A9 S¬ 172 172 170 172 194 00AC S® 174 174 169 174 168 00AE S¯ 175 175 238 175 248 00AF S° 176 176 248 176 161 00B0 S± 177 177 241 177 177 00B1 S´ 180 - 239 180 171 00B4 S¶ 182 182 244 182 166 00B6 S¸ 184 - 247 184 252 00B8 S× 215 215 158 215 - 00D7 S÷ 247 247 246 247 214 00F7 S

Page 442: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

450 Perl pour les linguistes

Extensions : Lettres minusculesCar. Latin1 Latin9 CP850CP1252MacRomanUnicodePropriétés

f - - 159 131 196 0192 Llœ - 189 - 156 207 0153 Llž - 184 - 158 - 017E Llš - 168 - 154 - 0161 Llı - - 213 - 245 0131 Llª 170 170 166 170 187 00AA Llµ 181 181 230 181 181 00B5 Llº 186 186 167 186 188 00BA Llß 223 223 225 223 167 00DF Llà 224 224 133 224 136 00E0 Llá 225 225 160 225 135 00E1 Llâ 226 226 131 226 137 00E2 Llã 227 227 198 227 139 00E3 Llä 228 228 132 228 138 00E4 Llå 229 229 134 229 140 00E5 Llæ 230 230 145 230 190 00E6 Llç 231 231 135 231 141 00E7 Llè 232 232 138 232 143 00E8 Llé 233 233 130 233 142 00E9 Llê 234 234 136 234 144 00EA Llë 235 235 137 235 145 00EB Llì 236 236 141 236 147 00EC Llí 237 237 161 237 146 00ED Llî 238 238 140 238 148 00EE Llï 239 239 139 239 149 00EF Llð 240 240 208 240 - 00F0 Llñ 241 241 164 241 150 00F1 Llò 242 242 149 242 152 00F2 Lló 243 243 162 243 151 00F3 Llô 244 244 147 244 153 00F4 Llõ 245 245 228 245 155 00F5 Llö 246 246 148 246 154 00F6 Llø 248 248 155 248 191 00F8 Llù 249 249 151 249 157 00F9 Llú 250 250 163 250 156 00FA Llû 251 251 150 251 158 00FB Llü 252 252 129 252 159 00FC Llý 253 253 236 253 - 00FD Llþ 254 254 231 254 - 00FE Llÿ 255 255 152 255 216 00FF Ll

Page 443: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Codage des caractères 451

Extensions : Lettres majusculesCar. Latin1 Latin9 CP850CP1252MacRomanUnicodePropriétés

Ž - 180 - 142 - 017D LuŸ - 190 - 159 217 0178 LuŒ - 188 - 140 206 0152 LuŠ - 166 - 138 - 0160 LuÀ 192 192 183 192 203 00C0 LuÁ 193 193 181 193 231 00C1 Lu 194 194 182 194 229 00C2 Luà 195 195 199 195 204 00C3 LuÄ 196 196 142 196 128 00C4 LuÅ 197 197 143 197 129 00C5 LuÆ 198 198 146 198 174 00C6 LuÇ 199 199 128 199 130 00C7 LuÈ 200 200 212 200 233 00C8 LuÉ 201 201 144 201 131 00C9 LuÊ 202 202 210 202 230 00CA LuË 203 203 211 203 232 00CB LuÌ 204 204 222 204 237 00CC LuÍ 205 205 214 205 234 00CD LuÎ 206 206 215 206 235 00CE LuÏ 207 207 216 207 236 00CF LuÐ 208 208 209 208 - 00D0 LuÑ 209 209 165 209 132 00D1 LuÒ 210 210 227 210 241 00D2 LuÓ 211 211 224 211 238 00D3 LuÔ 212 212 226 212 239 00D4 LuÕ 213 213 229 213 205 00D5 LuÖ 214 214 153 214 133 00D6 LuØ 216 216 157 216 175 00D8 LuÙ 217 217 235 217 244 00D9 LuÚ 218 218 233 218 242 00DA LuÛ 219 219 234 219 243 00DB LuÜ 220 220 154 220 134 00DC LuÝ 221 221 237 221 - 00DD LuÞ 222 222 232 222 - 00DE Lu

Tableau A2.4.Les principaux caractères latins dans les différents codes, etleurs principales propriétés Unicode

Page 444: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

452 Perl pour les linguistes

CodeLatin1 Latin9 CP850CP1252MacRoman

128 Ç C Ä129 ü Å130 é , Ç131 â f É132 ä „ Ñ133 à ... Ö134 å † Ü135 ç ‡ á136 ê à137 ë ‰ â138 è Š ä139 ï ‹ ã140 î Œ å141 ì ç142 Ä Ž é143 Å è144 É ê145 æ ‘ ë146 Æ ’ í147 ô “ ì148 ö ” î149 ò • ï150 û - ñ151 ù -- ó152 ÿ ~ ò153 Ö ™ ô154 Ü š ö155 ø › õ156 £ œ ú157 Ø ù158 × ž û159 f Ÿ ü160 á †161 ¡ ¡ í ¡ °162 ¢ ¢ ó ¢ ¢163 £ £ ú £ £164 ¤ C ñ ¤ §165 ¥ ¥ Ñ ¥ •166 ¦ Š ª ¦ ¶167 § § º § ß168 ¨ š ¿ ¨ ®

Page 445: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Codage des caractères 453

CodeLatin1 Latin9 CP850CP1252MacRoman

169 © © ® © ©170 ª ª ¬ ª ™171 « « ½ « ´172 ¬ ¬ ¼ ¬ ¨173 ¡ 6=174 ® ® « ® Æ175 ¯ ¯ » ¯ Ø176 ° ° ° ∞177 ± ± ± ±178 2 2 2 ≤179 3 3 3 ≥180 ´ Ž ´ ¥181 µ µ Á µ µ

182 ¶ ¶ Â ¶ ∂

183 · · À ·∑

184 ¸ ž © ¸∏

185 1 1 1 π

186 º º º∫

187 » » » ª188 ¼ Œ ¼ º189 ½ œ ¢ ½ Ω190 ¾ Ÿ ¥ ¾ æ191 ¿ ¿ ¿ ø192 À À À ¿193 Á Á Á ¡194    ¬195 à à Ã

196 Ä Ä Ä f

197 Å Å Å ≈198 Æ Æ ã Æ

199 Ç Ç Ã Ç «200 È È È »201 É É É ...202 Ê Ê Ê203 Ë Ë Ë À204 Ì Ì Ì Ã205 Í Í Í Õ206 Î Î Î Œ207 Ï Ï ¤ Ï œ208 Ð Ð ð Ð -209 Ñ Ñ Ð Ñ --

Page 446: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

454 Perl pour les linguistes

CodeLatin1 Latin9 CP850CP1252MacRoman

210 Ò Ò Ê Ò “211 Ó Ó Ë Ó ”212 Ô Ô È Ô ‘213 Õ Õ ı Õ ’214 Ö Ö Í Ö ÷215 × × Î × ♦

216 Ø Ø Ï Ø ÿ217 Ù Ù Ù Ÿ218 Ú Ú Ú 219 Û Û Û C220 Ü Ü Ü ‹221 Ý Ý ¦ Ý ›222 Þ Þ Ì Þ fi223 ß ß ß fl224 à à Ó à ‡225 á á ß á ·226 â â Ô â ,227 ã ã Ò ã „228 ä ä õ ä ‰229 å å Õ å Â230 æ æ µ æ Ê231 ç ç þ ç Á232 è è Þ è Ë233 é é Ú é È234 ê ê Û ê Í235 ë ë Ù ë Î236 ì ì ý ì Ï237 í í Ý í Ì238 î î ¯ î Ó239 ï ï ´ ï Ô240 ð ð ð 241 ñ ñ ± ñ Ò242 ò ò ò Ú243 ó ó ¾ ó Û244 ô ô ¶ ô Ù245 õ õ § õ ı246 ö ö ÷ ö

247 ÷ ÷ ¸ ÷ ~248 ø ø ° ø ¯249 ù ù ¨ ù ˘250 ú ú · ú ·

Page 447: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Codage des caractères 455

CodeLatin1 Latin9 CP850CP1252MacRoman

251 û û 1 û ˚252 ü ü 3 ü ¸253 ý ý 2 ý ˝254 þ þ þ ˛255 ÿ ÿ ÿ ˇ

Tableau A2.5.Table combinée deLatin1, Latin9, CP850, CP1252etMacRoman

Page 448: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

456

Page 449: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

ANNEXE 3

Localisation

Les opérations de manipulation informatique de données linguistiques sont natu-rellement confrontées aux spécificités des langues dont relèvent ces données. Il estheureusement possible, dans certains systèmes d’exploitation mais également dans lelangage Perl d’adapter le traitement. Cette opération d’adaptation porte le nom delo-calisation(ou l10ncomme aiment à l’abréger les informaticiens). Nous en présentonsici les grands principes, et en donnons les implications concrètes pour les manipula-tions de données abordées dans cet ouvrage.

A3.1. Généralités

Le principe de la localisation concerne en général l’adaptation d’un outil infor-matique à une langue ou une culture autre que celle dans laquelle elle a été initia-lement développée. Dans le cadre du traitement automatiquedes données textuelles,les aspects linguistiques sont bien sûr les principaux impliqués. La plupart des outilssystèmes génériques, ainsi que les langages de programmation, lorsqu’ils abordent lesdonnées de type texte, ont comme comportement par défaut de considérer que celles-ci sont en anglais. Dès lors, un travail informatique sur le français, ou toute autrelangue utilisant le même alphabet, pose des problèmes bien précis. Parmi ceux quenous détaillons, citons :

– les caractères « supplémentaires » utilisés par la langue :quels sont-ils, com-ment doit-on les traiter ? Par exemple, le caractère ‘é’ peut-il se trouver dans un mot,et si oui, comment se comporte-t-il dans un tri lexicographique (comme un ‘e’, ouautrement)?

– les dates (jours, mois, heures) s’expriment-elles en utilisant les mêmes standardsque l’anglais/américain?

457

Page 450: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

458 Perl pour les linguistes

– les valeurs numériques (symbole des décimales, groupement des chiffres pourune meilleure lisibilité) sont-elles exprimées de façon différente?

Il faut noter que l’on parle généralement de localisation d’un outil informatique dèslors que l’interface utilisateur de celui-ci doit utiliserune autre langue, par exemplepour les messages d’erreurs, les textes des boutons et menus, la documentation, etc.Certains aspects culturels (par exemple liés aux connotations de certains termes, ou àla symbolique des couleurs, à la disposition des éléments d’un texte ou d’une fenêtre,etc.) font également partie de ce concept. Toutefois, nous nous limitons ici aux aspectsstrictement liés à la manipulation de données de type texte,et à la prise en compte desspécificités du français (et d’autres langues occidentalespar extension). Plus formelle-ment, les systèmes Unix intègrent tous dans leur configuration la possibilité d’indiquerla langue et le pays dont les normes doivent influencer la manipulation de certainesdonnées. Ces paramètres sont connus sous le nom delocalesou paramètres de loca-lisation. Ils peuvent être changés dynamiquement par un utilisateur, et influencent lefonctionnement des outils qui en tiennent compte.

A3.2. Les paramètreslocales

A3.2.1. Langage de description deslocales

La définition deslocalesrépondent à une norme internationale. La définition d’unenvironnement localisé s’exprime par une chaîne de caractère spécifique, dont le for-mat est le suivant :

<langue>_<PAYS>.<codage>

Si ce format général est le même pour les différents systèmesd’exploitation, lesvaleurs possibles pour chaque position sont malheureusement dépendantes des choixdes concepteurs de ces systèmes. La différence principale se fait là encore entre lessystème de type Unix et les systèmes Windows.

La langues’exprime sous Unix par les deux lettres du code international ISO-639-1, et sous Windows par une chaîne de caractère correspondant au nom anglais de cettelangue. Les codes de quelques langues européennes à titre indicatif dans le tableauA3.11.

1. La liste complète des codes est disponible sur le site du W3Cpour Unix :http://www.w3.org/WAI/ER/IG/ert/iso639.htmet sur le site de Microsoft pour Windows :http://msdn.microsoft.com/library/en-us/vclib/html/ _crt_Language_and_Country_Strings.asp .

Page 451: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Localisation 459

Langue CodeISO639 Code Microsoftallemand de germananglais en englisharabe ar -espagnol es spanishfrançais fr frenchgrec el greekitalien it italianjaponais ja japanese

Tableau A3.1.Exemples de codes pour quelques langues

Le payss’exprime également sous Unix par un code abrégé de deux lettres suivantla normeISO-3166-1-alpha-2. Sous Windows, le code à utiliser est soit le nom an-glais du pays, soit un code de trois lettres inspiré de la norme ISO. Cette spécificationde second niveau permet d’adapter le traitement à des particularités nationales. Parexemple, pour le français, les codes des différents pays sont indiqués dans le tableauA3.22.

Pays Code ISO3166Code MicrosoftBelgique BE BelgiumCanada CA CanadaFrance FR FranceLuxembourg LU -Suisse CH Switzerland

Tableau A3.2.Exemples de codes nationaux pour les pays francophones

Enfin, lecodagecorrespond à la table de codage de caractères utilisée, voiran-nexe A2. Par exemple, le paramètre :

fr_FR.ISO88591

indique sous Unix une localisation en français (fr ), avec les usages nationaux de laFrance (FR), et un codage des caractères enLatin1 (ISO88591 ). Sous Windows, leparamètre :

french_France.1252

2. La liste complète des pays pour le code ISO3166 est disponible librement sur le site duconsortium Unicode :http://www.unicode.org/onlinedat/countries.html .Pour les codes Microsoft, la liste est disponible sur la mêmepage que pour les langues.

Page 452: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

460 Perl pour les linguistes

indique la même localisation, mais avec un codage enCP1252. Il n’est toutefois paspossible sous Windows d’indiquer dans les locales qu’on utilise un codageUTF-8.Ceci pose des problèmes pour l’utilisation de données en Unicode sous Windows.

Enfin, il est important de noter que dans le cas des systèmes non localisés, la valeurpar défaut de la localisation estC ou POSIX. Ces valeurs indiquent que le compor-tement des programmes doit se faire par défaut, en utilisantgénéralement les normesanglo-saxonnes correspondantes. Cette valeur indique généralement sous Unix que lesystème peut être localisé, mais que la décision doit être prise par l’utilisateur.

A3.2.2. Paramètres localisables

L’impact de ces paramètres sur le fonctionnement du systèmeet/ou des pro-grammes dépend de plusieurs variables. Plus précisément, il est possible, sous unsystème de type Unix (mais également dans un programme Perl,comme on le verraplus loin), d’utiliser des paramètres de localisation pourcertaines opérations unique-ment. Pour ce faire, il existe six variables d’environnement auxquelles il est possibled’affecter directement un des codes décrits précédemment.Ces variables sont :

Variable Définition Exemples de paramètres

LC_CTYPE Classes de caractères etparamètres de conversion

Statut des caractères accentuées, conversionsmajuscules/minuscules entre les caractèresaccentués

LC_COLLATE Ordre des caractères Emplacement des caractères accentués dansl’ordre lexicographique

LC_MONETARYFormat monétaire Symbole de la monnaie, position de celui-cipar rapport au montant

LC_NUMERIC Format numérique nonmonétaire

Symbole des décimales, groupement desmilliers, symbole séparant ces groupements

LC_TIME Format des dates etdes heures

Noms des jours et mois, ordre desinformations (jour, mois, année)

LC_MESSAGESFormat des messages Langue dans laquelle sont écrits les messagesd’erreur ou les manuels en ligne

En plus de ces six variables, il en existe une septième, dont le seul rôle est derépercuter sa valeur sur les six autres, afin d’accélérer lesmodifications de paramètres :LC_ALL.

Chacune de ces variables peut donc, à un moment donné de l’utilisation d’un sys-tème Unix ou d’un programme Perl, avoir une valeur qui modifiera le comportementdu programme. Nous détaillons plus précisément l’impact decertaines de ces variablespour le traitement linguistique dans la section suivante.

Page 453: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Localisation 461

A3.3. Impact des locales sur le traitement linguistique

A3.3.1. Principaux problèmes rencontrés

Les problèmes classiques rencontrés par un traitement non localisé sont les sui-vants :

– les caractères accentués ou avec diacritiques ne peuvent pas être utilisés par leprogramme;

– ces caractères peuvent être utilisés, mais pas comme des lettres, notamment dansles expressions régulières utilisant des classes prédéfinies ;

– les conversions automatiques entre majuscules et minuscules ne prennent pas encompte les lettres accentuées ;

– les opérations de comparaison ou de tri positionnent les caractères accentuésaprès leur version sans accent ;

– les nombres décimaux utilisent le point comme séparateur des décimales au lieude la virgule.

De tels problèmes interviennent lorsque le système est non ou mal localisé. Nousallons voir dans la section suivante les moyens concrets d’yremédier.

A3.3.2. Sous un système Unix

La valeur des paramètres de localisation en cours est accessible simplement entapant la commande :

locale

En réponse, le système affiche en sortie standard la valeur delocalisation de cha-cune des variables. Les valeurs « C » ou « POSIX » indiquent quela localisation n’apas été faite.

Pour modifier les valeurs, il suffit d’attribuer une nouvellevaleur aux différentesvariables d’environnement (via la commandeexport ou setenven fonction du shellutilisé). Toutefois, la valeur attribuée à ces variables doit correspondre à des ressourcesdéfinies sur le système.

Les locales disponibles sur le système sont sous la responsabilité de l’administra-teur. Dès lors, en fonction du système lui-même, et des installations qui ont été faites,vous pouvez avoir à votre disposition une grande variété delocales. La liste complèteest fournie par la commande :

locale -a

Page 454: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

462 Perl pour les linguistes

La modification des locales sous Unix permet également de modifier le codagedes caractères par défaut. Ainsi, le passage à un environnementUnicodesous Unix sefait nécessairement par la modification de ces variables, avecUTF-8comme troisièmeélément pour la chaîne de localisation. Comme indiqué dans l’annexe A2, le passagesous un codage différent peut nécessiter la modification de la police de caractèresutilisée par le terminal.

A3.3.3. Sous Windows

La modification des paramètres de localisation sous Windowsn’est pas possibledirectement dans un terminal. Les paramètres de localisation sont fixés directementau niveau du système Windows. Les variables de localisationcitées précédemment nesont pas des variables d’environnement dont on puisse visualiser ou modifier la valeur.

Ainsi, un système Windows configuré en français correspondra à un paramètre delocalisation du typefrench_France.1252 .

La gestion des environnements multilingues de Windows n’influence pas ce para-mètre, mais se contente, en ce qui concerne les terminaux de modifier la configurationdu clavier.

A3.3.4. En Perl

Le comportement par défaut d’un programme Perl est de ne pas être localisé, mêmesi le système l’est. Cela veut dire notamment que les caractères accentués quels qu’ilssoient ne sont pas considérés comme des lettres, qu’ils sontplacés après les lettressans accents lors d’un tri, et qu’il n’est pas possible de lesconvertir en majusculeou minuscule. De même, les nombres, dates et heures sont affichés selon la normeanglo-saxonne.

A3.3.4.1. Le modulelocale

Le modulelocale de Perl permet de remédier à cet état de fait en adaptant toutesles fonctionnalités impliquées aux paramètres de localisation du système. L’instructionsuivante :

use locale;

placée en début de programme, permet donc bien souvent de résoudre les différentsproblèmes cités, pour peu que le système d’exploitation soit effectivement localisé.Toutefois, ce module seul ne permet pas la modification des paramètres de localisa-tion ; si la langue que votre programme doit traiter n’est pascelle qu’indique votresystème, il faut la préciser avec le modulePOSIX.

Page 455: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Localisation 463

REMARQUE.– L’utilisation de l’instructionuse locale dans un programme fonc-tionnant sous Windows peut, dans certains cas, ne pas positionner correctement toutesles variables de localisation. Il convient donc au cas par cas de vérifier le résultat desprogrammes et, le cas échéant, de fixer manuellement ces variables comme indiquéci-dessous.

A3.3.4.2. Le modulePOSIX

Le modulePOSIX donne accès à un ensemble considérable de fonctionnalitésétendue de Perl correspondant aux normes et recommandations pour les programmesinformatiques issues de l’institutIEEE3.

Parmi les fonctionnalités offertes par ce module, celle quenous traitons ici est liéeau paramétrage deslocales, et doit être activée par la ligne de code suivante :

use POSIX ’locale_h’;

Cette ligne doit être placéeaprèsla ligne «use locale; ». Dès lors, elle donneaccès à la fonctionsetlocale, dont la syntaxe est :

setlocale( VARIABLE, valeur );

Sous Unix, elle correspond à la modification d’une des variables systèmes de loca-lisation. Par exemple, pour préciser dans votre programme que la définition des classesde caractères à utiliser est celle correspondant au français de France en codageLatin1sous Unix, il faut insérer dans votre code la ligne :

setlocale(LC_CTYPE, "fr_FR.ISO88591");

Toute instruction localisée située dans la suite du programme utilisera donc ceparamètre. De plus, il est tout à fait possible de changer de paramètre de localisationen cours de programme, si l’on a à traiter des données multilingues.

Les restrictions dans les valeurs utilisées sont les mêmes que vues précédemment,à savoir :

– sous Unix, leslocalesutilisées doivent avoir été définies au niveau du système ;

– sous Windows, leslocalessont fixées par Microsoft, mais toutes sont dispo-nibles. Toutefois, leur syntaxe est différente de celle d’Unix.

3. Institute of Electrical and Electronics Engineers.

Page 456: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

464 Perl pour les linguistes

A3.3.4.3. Opérateurs et fonctions localisées

Voici la liste des principaux opérateurs et fonctions de Perl dont le comportementest modifié par les paramètres de localisation :

– comparaison de chaînes.Les opérateurscmp, lt , gt , le et ge , permettantune comparaison de chaînes suivant l’ordre lexicographique prennent en compte leslettres accentuées et avec diacritiques en positionnant celles-ci au même niveau queleur version non accentuée. Ainsi, pour une localisation enfrançais, la lettreâ estsituée au même niveau quea, si bien que la chaînepâteest située avantpatte.Variable impliquée :LC_COLLATE;

– tri lexicographique.Par extension de ce qui précède, la fonctionsort, dans le casoù elle utilise une comparaison lexicographique pour trierles différentes chaînes, lefera sur le même principe.Variable impliquée :LC_COLLATE;

– changements de casse.Les fonctionsuc et lc permettant d’effectuer des chan-gements de casse, seront à-même de traiter des lettres accentuées. Ainsi, la valeur del’expression :uc("pâté") en mode localisé seraPÂTÉet non plusPâTé.Variable impliquée :LC_CTYPE;

– expressions régulières.La classe de caractères prédéfinie\w , censée contenir leslettres, chiffres et souligné (_) contient également les lettres accentuées (minusculeset majuscules) en mode localisé. Son complémentaire\W ne les contient donc plus.Il n’y a donc plus de frontière de mots (\b ) entre une lettre accentuée et une lettrenon accentuée. Enfin, les intervalles du type[a-z] contiennent également les lettresaccentuées, en conséquence de leur position dans l’ordre lexicographique.Variable impliquée :LC_CTYPE;

– affichage de valeurs numériques décimales.La fonctionsprintf , permettant no-tamment de formater une valeur numérique scalaire afin de limiter le nombre de dé-cimales, a comme effet supplémentaire d’adapter l’affichage en utilisant le caractèrelocalisé de séparateur des décimales. Ainsi, avec un paramétrage français la valeur del’expressionsprintf("%.2f", 3.14156) sera3,14 et non plus3.14 .Variable impliquée :LC_NUMERIC.

A3.3.4.4. Problèmes induits par la localisation

Le passage à un mode localisé pose néanmoins quelques problèmes au niveau dela manipulation de chaînes de caractères.

A3.3.4.4.1. Performance

L’utilisation de paramètres de localisation entraîne généralement une sensiblebaisse des performance d’un programme, notamment au niveaudes opérations detri, notoirement coûteuses en temps de calcul. La prise en compte des modificationsdans l’ordre des caractères consiste techniquement en une surcouche dans les opéra-tions fondamentales de comparaison de chaînes, et ralentissent donc l’exécution d’un

Page 457: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Localisation 465

programme. Toutefois, la différence n’atteint même pas un doublement du temps decalcul, et est donc tout à fait acceptable.

A3.3.4.4.2. Tri et majuscules

Un autre problème est que les caractères majuscules et minuscules n’ont plus deposition relative prédéfinie. Ainsi, les chaînes suivantes: Baba, babaet BABA sontsituées lexicographiquement au même niveau en mode localisé. Un exemple de consé-quences négatives est que, dans le cas du tri lexicographique d’une liste de mots ex-traits d’un texte brut, les distinctions de casse n’apparaissant plus comme résultat dutri. Pour ce faire, il est nécessaire de séparer explicitement les formes contenant desmajuscules de celles qui n’en contiennent pas si la distinction est pertinente.

A3.3.4.4.3. Tri et caractères séparateurs

Les comparaisons de chaînes suivant l’ordre lexicographique en mode localiséne tiennent plus compte des caractères d’espacement : la comparaison ne prend encompte que les lettres et chiffres. Cette situation est particulièrement problématiquedans le cas où l’on a à trier des chaînes complexes, par exemple des couples for-me/étiquette ou forme/lemme. Ainsi, si l’on demande une comparaison lexicogra-phique entre les chaînes :"marche VER" et "marcher VER" (c’est-à-dire deuxchaînes contenant chacune une forme suivie d’un espace et d’une étiquette morpho-syntaxique), la chaîne"marcher VER" sera placée avant, puisque l’espace n’estpas pris en compte. Les conséquences de cette situation sontdécrites au chapitre 6.

A3.4. Conclusion

Malgré les quelques problèmes induits pas la localisation présentés au paragrapheprécédent, nous considérons que l’utilisation de ces différentes procédures constitueun net progrès dans la manipulation de données linguistiques. Si de nombreux infor-maticiens et utilisateurs ont sufaire avecla maltraitance des lettres accentuées dansdes opérations de traitement lexical, les différentes technologies actuelles permettentde respecter les normes de la lexicographie et facilitent l’exploitation des donnéesproduites par les applications informatiques.

Page 458: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

466

Page 459: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

ANNEXE 4

Structures de données complexes et références

A4.1. Principes et cas d’utilisation

Perl dispose à la base de trois types de données fondamentaux: les scalaires, lestableaux et les hachages. Ces types de données permettent destocker des valeurs sca-laires (nombres ou chaînes de caractères), des séries de valeurs scalaires, ou des listesde couples (clé scalaire, valeur scalaire). Dans certainessituations, les données à sto-cker sont plus complexes, et correspondent à des représentation formelles comme desarbres syntaxiques ou des structures de traits. Dans ce cas,il est nécessaire, pour lesmanipuler dans un programme, de faire appel à des structuresde données complexesmélangeant plusieurs types de données fondamentaux.

Le principe de ces structures complexes est le suivant : là oùles tableaux et leshachages sont normalement limités au stockage de données scalaires, il est en faitpossible d’utiliser des tableaux ou des hachages. Il est parexemple possible de créerun tableau dans lequel les éléments sont des hachages (on parle alors de tableau dehachages), ou bien un hachage dans lequel les valeurs sont des tableaux (hachage detableaux). Cette imbrication peut se répéter autant de foisque nécessaire, créant ainsides structures de grande complexité.

La plupart des exemples de traitement présentés dans cet ouvrage ne font pas appelà de telles structures. Elles sont par contre inévitables lorsque l’on utilise dans unprogramme Perl des modules permettant de manipuler des données structurées, oulorsque l’on fait appel à la programmation objet. Plus précisément, ces situations seprésentent face à des données structurées en XML (voir chapitre 9) ou pour certainesutilisation des données issues du Web (voir chapitre 10).

467

Page 460: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

468 Perl pour les linguistes

A4.2. Références

Le principe fondamental à la base des structures complexes est celui de laréfé-rence. On appelle référence à une donnée quelconque un scalaire qui contient en faitl’adressede cette donnée dans la mémoire de l’ordinateur (dans d’autres langages deprogrammation, notamment C, les références sont égalementappeléespointeurs). Lafigure A4.1 représente comment un scalaire peut faire référence à un tableau.

Référence au Adresse dutableau @ttableau @t

@t

Tableau

Scalaire

A B C D E

Figure A4.1. Référence à un tableau

Il est possible, à partir de cette simple adresse, de manipuler les données qui y sontstockées, avec l’avantage majeur que la référence est un scalaire, et peut donc êtrestockée dans les cellules d’un tableau ou dans les valeurs d’un hachage. On peut parexemple stocker dans les cellules d’un tableau des références à d’autres tableaux etainsi obtenir untableau de tableaux, comme le montre la figure A4.2.

...

Référenceà @t1

Référenceà @t2

Référenceà @t3

@t1

@t2

@t3

A1 B1 C1 D1 E1

A2

A3 B3

B2 C2

C3 D3 E3

D2 E2

Tableau de tableaux

Figure A4.2. Structure d’un tableau de tableaux

La manipulation des références reste toutefois une opération délicate, faisant in-tervenir un ensemble de notations spécifiques qu’il est nécessaire de connaître avantd’aborder de telles structures complexes.

Page 461: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Structures de données complexes et références 469

A4.2.1. Création d’une référence

On obtient une référence à une variable quelconque en plaçant un caractère\ de-vant le nom complet de la variable :

– \$scal est une référence au scalaire$scal ;

– \@tab est une référence au tableau@tab ;

– \%hash est une référence au hachage%hash.

Comme une référence est un scalaire, il est tout à fait possible de la recopier dansune variable scalaire :

$reftab = \@tab;

La valeur ainsi obtenue et stockée dans la variable$reftab n’est toutefois pasutilisable directement. Si on affiche son contenu comme s’ils’agissait d’une chaîne decaractères (à l’aide deprint ), on obtient un résultat du type :

ARRAY(0X265d4) .

Cette chaîne affichée indique qu’il s’agit d’une référence àun tableau (ARRAY ) ;la valeur entre parenthèses est l’adresse de la zone de mémoire où est stocké le tableauen question. Pour une référence à un scalaire, on obtiendrait la chaîneSCALAR, etHASH pour un hachage.

A4.2.2. Référence à un tableau

Une variable$reftab contenant une référence à un tableau peut être utilisée dela manière suivante :

– on accède au tableau référencé par la notation@$reftab ; cette opérations’appelle undéréférencement;

– on peut ainsi stocker recopier le tableau référencé par$reftab dans une va-riable classique de type tableau :

@tableau = @$reftab;

– on peut accéder directement aux éléments du tableau référencé par leurs numérosde cellule. Ainsi, pour accéder au premier élément du tableau référencé par$reftabon peut utiliser la notation :

$$reftab[0]

ou : $$reftab[0]

ou encore :$reftab->[0] ;

– on peut enfin obtenir directement le rang du dernier élémentdu tableau référencépar la notation :$#$reftab .

Page 462: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

470 Perl pour les linguistes

Par exemple, on peut parcourir le tableau référencé par$reftab et en afficherles éléments de la façon suivante :

for ( my $i=0; $i <= $#$reftab; $i++ )

print $reftab->[$i];

ou encore, plus naturellement, en utilisant une boucleforeach :

foreach $element ( @$reftab )

print $element;

Il est possible de créer directement une référence à un tableau sans que ce tableaune soit stocké au préalable dans une variable. Ce type de référence est appeléanonyme.On crée une référence anonyme à un tableau en utilisant la notation suivante :

$reftab = [ "un", "deux", "trois" ];

Autrement dit, cette opération est strictement identique àcelle exprimée par lesdeux lignes de code suivantes :

@tab = ("un", "deux", "trois");$reftab = \@tab;

A4.2.3. Référence à un hachage

De la même façon que pour les tableaux, si la variable$refhash contient uneréférence à un hachage :

– le hachage référencé est accessible par%$refhash ;

– on peut recopier le hachage référencé dans une variable de type hachage :

%hash = %$refhash;

– on peut accéder directement aux valeurs du hachage référencé par leurs clés.Ainsi, pour accéder à la valeur associée à la clé"a" dans le hachage référencé par$refhash on peut utiliser la notation :

$$refhash"a"

ou : $$refhash"a"

ou encore :$refhash->"a" ;

– on peut afficher l’intégralité des couples (clé, valeur) stockés dans un hachageen utilisant sa référence de la façon suivante :

Page 463: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Structures de données complexes et références 471

foreach $cle ( keys %$refhash )

print $cle, " ", $refhash->$cle;

Enfin, comme pour les tableaux, il est possible de créer directement une référenceà un hachage anonyme en utilisant la notation suivante :

$refhash = "a" => 1, "b" => 2 ;

Cette opération étant ici aussi strictement identique à celle exprimée par les deuxlignes de code suivantes :

%hash = ( "a" => 1, "b" => 2);$refhash = \%hash;

A4.3. Manipulation de structures complexes

En utilisant les références, il est possible d’imbriquer des structures en se basantsur les tableaux et les hachages, en y stockant non plus de simples scalaires mais desréférences à des structures.

REMARQUE.– En ce qui concerne les hachages, seules lesvaleursqui y sont stockéessont susceptibles de contenir des références. Les clés d’unhachage quel qu’il soitdoivent toujours être des scalaires traditionnels.

A4.3.1. Exemple de structure complexe : hachage de tableaux

Dans ce premier exemple, nous stockons dans une seule structure complexe plu-sieurs listes de mots, et plus précisément les déverbaux nominaux de quelques verbes :

– élevera comme dérivésélevageet élévation;

– abattrea comme dérivésabattageetabattement;

– correspondrea comme dérivécorrespondance.

La structure utilisée est un hachage ayant comme clés les différents verbes. Lesvaleurs associées seront par contre des tableaux de noms, ouplus précisément desréférences à des tableaux.

Le code permettant de stocker ces informations est le suivant, en utilisant le ha-chage%derives :

$derives"élever" = [ "élevage", "élévation" ];$derives"abattre" = [ "abattage", "abattement" ];$derives"correspondre" = [ "correspondance" ];

Page 464: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

472 Perl pour les linguistes

Dans ce cas, on utilise des références anonymes à des tableaux. On peut bien en-tendu utiliser des variables de type tableau et remplacer par exemple la première ins-truction par la séquence suivante :

@tab = ( "élevage", "élévation" );$derives"élever" = \@tab;

Etant donné un verbe$verbe , on obtient la liste de ces dérivés par la notationsuivante :

@$derives$verbe

On trouve le premier dérivé deabattre(doncabattage) par :

$derives"abattre"->[0]

Si l’on souhaite ajouterélèvementaux dérivés du verbeéleveron utilisera :

push ( @$derives"élever", "élèvement" );

Enfin, pour afficher l’intégralité de la structure, on utilise le code suivant :

foreach my $verbe ( keys %derives )

print $verbe, "\t";

print join ( " ", @$derives$verbe ), "\n";

REMARQUE.– Il aurait également été possible d’utiliser uneréférenceà un hachageplutôt qu’un hachage pour stocker la structure globale. C’est cette solution qui estd’ailleurs utilisée pour ce type de structures quand elles sont construites dans desmodules Perl. L’avantage de cette solution est le même que pour n’importe quelle ré-férence : la structure elle-même est plus facilement manipulable (elle peut notammentêtre renvoyée comme résultat d’une fonction, comme indiquéplus loin). Dans ce cas,l’ensemble de la structure serait représentée par un scalaire qui serait une référence àun hachage complexe (dans notre exemple$ref_derives . Ceci donnerait commenotation pour son remplissage :

$ref_derives->"élever" = [ "élevage", "élévation" ];

et pour son utilisation :

@$ref_derives->"abattre" ,$ref_derives->"abattre"->[0] ,push ( @$ref_derives->"élever";

Page 465: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Structures de données complexes et références 473

et encore, pour afficher l’intégralité de son contenu :

foreach my $verbe ( keys %$ref_derives )

print $verbe, "\t";

print join ( " ", @$ref_derives->$verbe ), "\n";

Les principes présentés ici s’appliquent de la même façon à des structures du typetableau de hachages, hachage de hachages, etc. La profondeur d’une telle structurepeut bien entendu être plus importante, et l’on peut sur le même principe envisagerdes structures à plus de deux niveaux (hachage de tableaux dehachages, etc.).

Il est également possible de définir de la même manière des structures dans les-quelles les informations sont de profondeur variable, et oùle type des structures im-briquées peut varier d’un élément à l’autre.

A4.3.2. Structures complexes hétérogènes

On appelle structure hétérogène une structure de données complexe dans laquellela nature des éléments imbriqués varie d’un élément à l’autre. C’est le cas, parexemple, d’un tableau dont les cellules contiennent à la fois des scalaires et des ré-férences à des hachages. La profondeur d’une telle structure est donc variable, commec’est le cas pour les arbres et les structures de traits.

Dans l’exemple de la figure A4.3, nous présentons sous forme traditionnelle unepartie d’un lexique morphologique indiquant pour chaque mot sa catégorie grammati-cale et des listes de dérivés de ce mot classés par catégorie.

abattre ⇒

categorie⇒ verbe

morphologie⇒

nom⇒ abattement , abattage

adj⇒ abattable

agricole ⇒

categorie⇒ adjectif

morphologie⇒

nom⇒ agriculteur , agriculture

Figure A4.3. Exemple de structure de traits

La structure de données nécessaire pour représenter en Perlcet ensemble d’infor-mations est plus élaborée que celles vues dans la section précédentes : au troisièmeniveau on peut trouver soit un scalaire (pour indiquer la catégorie d’une entrée) soitune structure (pour indiquer les listes de dérivés classés par catégorie).

Page 466: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

474 Perl pour les linguistes

Toutefois, l’utilisation de références donne la souplessesuffisante pour représenterle tout dans une structure dont la description est la suivante :

– globalement, il s’agit d’un hachage avec les entrées du lexique comme clés ;

– à chaque entrée est associé un hachage, donc les clés sont les noms des traits(catégorieet morphologie) ;

– à la clécatégorieest simplement associée le scalaire correspondant à celle-ci(verbe, adjectif) ;

– à la clémorphologieest associé un nouveau hachage, dont les clés sont les caté-gories des mots de la famille morphologique;

– enfin, à chacune de ces catégories est associée la liste des mots morphologique-ment liés, sous forme de tableau.

En termes de code Perl, cela donne la structure suivante, entièrement stockée dansla référence$lexique :

$lexique =

"abattre" =>

"catégorie" => "verbe",

"morphologie" =>

"nom" => [ "abattement", "abattage" ],

"adj" => [ "abattable"]

,

"agricole" =>

"catégorie" => "adjectif",

"morphologie" =>

"nom" => [" agriculteur", "agriculture" ]

;

Il est également possible de remplir cette structure au fur et à mesure, en ajou-tant les éléments depuis la clé primaire (l’entrée dans le lexique) jusqu’aux valeursassociées aux traits.

Le principe des notations permettant d’accéder au contenu de cette structure est departir des niveaux les plus élevés (les entrées), et de descendre vers les informationsniveau par niveau (les traits principaux, puis les valeurs associées, etc.).

Les informations suivantes sont ainsi accessibles par les notations :

– catégorie de l’entréeagricole:

$lexique->"agricole"->"catégorie" ;

Page 467: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Structures de données complexes et références 475

– premier nom morphologiquement lié àagricole:

$lexique->"agricole"->"morphologie"->"nom"->[ 0] ;

– liste des adjectifs morphologiquement liés àabattre:

@$lexique->"abattre"->"morphologie"->"adj" .

Ce type de structure souple est celui qui est utilisé dans certaines applications pourreprésenter des données structurées, notamment celles issues de documents au formatXML (voir chapitres 9 et 10). Bien entendu, leur manipulation demande de la part duprogrammeur une connaissance exacte de l’architecture de la structure, mais une foiscelle-ci connue son utilisation est relativement simple.

A4.4. Notions connexes

Nous présentons dans cette section un ensemble de notions dela syntaxe de Perlqui font appel aux principes des références ou des structures complexes.

A4.4.1. Passage de paramètres à une fonction

La notion de référence peut s’appliquer à différentes situations en Perl, notam-ment dans les cas où la syntaxe de Perl impose l’emploi d’un scalaire. C’est le casdu passage de paramètres à une fonction : cette opération se fait nécessairement parl’utilisation d’un tableau de scalaires (via la variable spéciale@_), comme indiqué ensection 3.10 (page 156). Dans certains cas toutefois, il peut être nécessaire de passeren paramètre une structure de données, comme un hachage. Pour ce faire, il suffit dèslors de communiquer à la fonction non pas le hachage lui-mêmemais une référenceà ce hachage. A titre d’exemple, la fonctionaffiche_hachage ci dessous reçoitune référence à un hachage et affiche son contenu, un couple (clé, valeur) par ligne :

sub affiche_hachage

my $ref_hash = shift @_;

foreach my $cle ( keys %$ref_hash )

print $cle, " ", $ref_hash->$cle, "\n";

Pour appliquer cette fonction à un hachage%exemple dont on souhaite afficherle contenu, il est nécessaire de passer comme paramètre à la fonction une référencesur%exemple , en utilisant la notation suivante :

affiche_hachage( \%exemple );

Ce principe peut également s’appliquer aux valeurs de retour d’une fonction, enutilisant exactement le même principe.

La fonctionconstruit_hachage renvoie un hachage (toujours le même) entant que référence :

Page 468: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

476 Perl pour les linguistes

sub construit_hachage

my %hash = ("a" => 1, "b" => 2);

return \%hash;

Pour utiliser le résultat de cette fonction, par exemple en stockant le hachage dansla variable%h, on peut par exemple utiliser la notation suivante :

%h = % construit_hachage() ;

A4.4.2. Références à des fonctions

Le principe des références peut également s’appliquer à d’autres entités comme lesfonctions et les descripteurs de fichiers. Ces cas d’utilisation restent assez restreints,mais peuvent être rendus nécessaires par l’utilisation de modules Perl spécifiques.

On obtient une référence sur une fonction en plaçant\& devant le nom de la fonc-tion. Ainsi, si pluriel est une fonction qui construit le pluriel d’un nom singulierpassé en paramètre, on obtient une référence à cette fonction par la notation :

\&pluriel

Si la variable$ref_fonction contient une référence à une fonction, l’exécu-tion de la fonction référencée se fait par la notation suivante :

&$ref_fonction ( ... );

en précisant les paramètres de façon classique.

Il devient dès lors possible de stocker des fonctions par référence dans un tableauou un hachage, mais surtout de passer une fonction comme paramètre à une autrefonction. L’exemple ci-dessous montre comment on peut communiquer à une fonctionnon seulement des données, mais aussi un traitement à appliquer à ces données. Lafonctionapplique_affiche_tableau reçoit en paramètre une référence à untableau et une référence à une fonction, et affiche, pour chaque élément du tableau lerésultat de la fonction passée en paramètre :

sub applique_affiche_tableau

my $ref_tab = shift @_;

my $ref_fonction = shift @_;

foreach my $element ( @$ref_tab )

print &$ref_fonction( $element ), "\n";

Par exemple, si l’on souhaite afficher le contenu d’un tableau @lexique en ap-pliquant la fonctionpluriel à ses valeurs, il suffit d’utiliser l’instruction suivante :

Page 469: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Structures de données complexes et références 477

applique_affiche_tableau ( \@lexique, \&pluriel );

Si l’on dispose d’une seconde fonction, par exemplelemme qui calcule le lemmed’un mot, elle peut également être appliquée aux éléments dulexique par :

applique_affiche_tableau ( \@lexique, \&lemme );

A4.4.3. Références à des descripteurs de fichiers

Il est également possible de manipuler des descripteurs de fichiers par référence. Ilest ainsi possible de passer des descripteurs comme paramètre à des fonctions, voirede gérer des listes de descripteurs.

Un descripteur de fichier n’est référençable qu’une fois qu’il a été créé, c’est-à-dire une fois que la fonctionopen lui a été appliquée avec succès. Les flux d’entrée etde sortie standards (STDIN et STDOUT) peuvent également être référencés.

Si le descripteurFIC correspond à un fichier ouvert (que ce soit en lecture ou enécriture), on en obtient une référence par la notation :

\ * FIC

Si $ref_descripteur_lecture contient est une référence à un descripteurde fichierouvert en lecture(ou une référence àSTDIN), on peut l’utiliser directementpour lire des données de la façon suivante :

my $ligne = <$ref_descripteur_lecture>;

Si $ref_descripteur_ecriture contient est une référence à un descrip-teur de fichierouvert en écriture(ou une référence àSTDOUT), on peut l’utiliser di-rectement pour y écrire des données :

print $ref_descripteur_ecriture "Ligne de texte\n";

Dans tous les cas (lecture ou écriture), il est également possible de fermer le des-cripteur référencé en utilisant :

close ( $ref_descripteur );

A4.4.4. Programmation orientée objet en Perl

Si la programmation orientée objet, possible en Perl, n’entre pas dans le cadrede cet ouvrage, certaines notions sont toutefois nécessaires pour utiliser correctementcertains modules de Perl.

Ce que l’on nomme objet en programmation est une représentation d’un type d’in-formation (un arbre, un lexique, un document, etc.) auquel sont associés un ensemble

Page 470: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

478 Perl pour les linguistes

de traitements préconçus (création, affichage, modification, etc.). L’intérêt majeur desobjets est que l’on peut les utiliser dans un programme sans avoir à en connaître exac-tement le fonctionnement interne. Il s’agit donc du meilleur moyen connu à l’heureactuelle de partager des traitements entre plusieurs programmes. C’est l’une des rai-sons pour lesquelles la plupart des modules disponibles en Perl prennent la formed’objets, et permettent de manipuler aisément des informations d’un certain type.

Ce que l’on nomme objet en Perl est techniquement une référence à un hachage.Les clés de ce hachage sont les noms des caractéristiques de cet objet (appeléesattri-buts) ou les noms des opérations possibles sur cet objet (appelées méthodes). L’utili-sation d’un objet en Perl utilise donc la notation des structures complexes vue précé-demment. Le principe de la syntaxe orientée objet de Perl est, dans une instruction,d’évoquer l’objet sur lequel porte le traitement, puis le traitement lui-même.

Prenons comme exemple le parseur XML du moduleXML::Parser , utilisé auchapitre 9. Les lignes de code spécifiques à l’utilisation dece type d’objet sont :

use XML::Parser;

$parseur = new XML::Parser;

$parseur -> setHandlers (

Start => \&balise_ouvrante

);

$parseur -> parsefile( "fichier.xml" );

La première ligne indique que l’on va utiliser un ou plusieurs objets du typeXML::Parser . La variable$parseur va contenir une référence à un objet de cetype, et elle est initialisée en utilisant le mot-clénew suivi du nom de l’objet. Lesdeux autres instructions sont des exemples d’utilisation de méthodes propres à ce typed’objet : setHandlerset parsefile sont en fait des fonctions définies pour les objetsdu typeXML::Parser et disponiblesvia le hachage référencé par$parseur . Ony retrouve la notation habituelle pour ce genre de structure(-> ).

On notera également que les paramètres passés à la méthodesetHandlerssontstockés dans un hachage anonyme. Ce hachage contient un seulcouple (clé, valeur) :la clé estStart (une chaîne arbitraire fixée par les concepteurs de la méthode), et lavaleur associée est une référence à une fonction définie dansle code de l’utilisateur.

A4.5. Pour en savoir plus

Cette annexe ne fait qu’effleurer les possibilités de structures complexes et de pro-grammation orientée objet en Perl. Pour en savoir plus, la documentation la plus com-plète est disponible en ligne par la commandeperldoc, et notamment les rubriquessuivantes :perlref (références en Perl),perlobj (programmation objet en Perl),perlboot (initiation à la programmation objet). De plus, une documentationperldocest disponible pour chaque module spécifique.

Page 471: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

ANNEXE 5

Référence des principales notions de Perl

Cette annexe récapitule l’ensemble des principales notions de Perl utilisées dansl’ouvrage. Elle est conçue pour être consultée en tant qu’aide-mémoire. En aucun caselle ne peut se substituer à une présentation plus détailléedans le reste de l’ouvrage,ni être aussi exhaustive que la documentation en ligne de Perl.

A5.1. Syntaxe générale

A5.1.1. Structure d’un programme

Un programme Perl doit avoir une entête comprenant les appels aux modules uti-lisés dans le programme. Les deux modules fondamentaux sont:

use strict;use locale;

Les instructions qui composent le programme doivent toutesêtre séparées par despoints-virgules (; ).

A5.1.2. Variables

Variable de type scalaire :$nom

Variable de type tableau :@nom

Variable de type hachage :%nom

479

Page 472: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

480 Perl pour les linguistes

Déclaration de variable : my variable

La déclaration doit se faire à la première utilisation d’unevariable. Une variabledéclarée dans un bloc n’est utilisable qu’à l’intérieur de ce bloc.

Le nom d’une variable doit commencer par une lettre non accentuée et ne contenirque des lettres non accentuées, des chiffres ou et le caractère souligné (_). La diffé-rence majuscule/minuscule est significative.

A5.1.3. Affectation

Affectation simple :

variable = expression ;

Affectation multiple de scalaires :

( scalaire_1 , scalaire_2 , ... ) = liste ;

A5.1.4. Entrées – Sorties

Affichage d’une valeur en sortie standard :print valeur

Affichage d’une liste de valeurs en sortie standard :print valeur_1 , valeur_2, ...

Lecture d’une ligne en entrée standard et stockage dans la variable $var :$var = <STDIN>;

Suppression du caractère de fin de ligne à la fin de la chaîne$chaine :chomp $chaine;

Ecriture d’un message d’erreur :warn message ;

Arrêt du programme avec émission d’un message d’erreur :die message ;

Page 473: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Référence des principales notions de Perl 481

A5.1.5. Notation des caractères spéciaux

A utiliser dans les chaînes de caractères constantes entre guillemets doubles :

Fin de ligne : \n

Tabulation : \t

Guillemet double : \"

Barre oblique inverse : \\

A5.1.6. Conditionnelles

Structure générale :if ( condition_1 )

bloc 1elsif ( condition_2 )

bloc 2else

bloc_final

A5.1.7. Boucles

Bouclewhile :while ( condition )

bloc

Boucle for :for ( initialisation ; condition ; progression )

bloc

Exemple :for (my $i = 0 ; $i <= 10 ; $i++) ...

Boucle foreach :foreach variable ( liste )

bloc

Page 474: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

482 Perl pour les linguistes

Sortie de la boucle en cours :last;

A5.2. Opérateurs fondamentaux

A5.2.1. Opérations sur les chaînes

Concaténation :chaîne_1 . chaîne_2

Calcul de la longueur : length ( chaîne )

Passage en minuscules :lc chaîne

Passage en majuscules :uc chaîne

Extraction de sous-chaîne :substr ( chaîne , début , longueur )

Exemple :substr ("lapin", 1, 3) vaut"api"

Egalité (condition) : chaîne_1 eq chaîne_2

Différence (condition) : chaîne_1 ne chaîne_2

Antériorité stricte dans l’ordre lexicographique (condit ion) :chaîne_1 lt chaîne_2

Antériorité dans l’ordre lexicographique ou égalité (condition) :chaîne_1 le chaîne_2

Postériorité stricte dans l’ordre lexicographique (condition) :chaîne_1 gt chaîne_2

Postériorité dans l’ordre lexicographique ou égalité (condition) :chaîne_1 ge chaîne_2

Correspondance avec une expression régulière (condition):chaîne =~ / expression / options

Substitution par une expression régulière :chaîne =~ s / expression / remplacement / options

Découpage d’une chaîne à l’aide d’un séparateur exprimé parune expressionrégulière :

tableau = split ( / expression /, chaîne )

Page 475: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Référence des principales notions de Perl 483

A5.2.2. Opérations sur les valeurs numériques

Opérateurs arithmétiques :+ - / *

Calcul du logarithme népérien : log ( valeur )

Egalité (condition) : valeur_1 == valeur_2

Différence (condition) : valeur_1 != valeur_2

Inférorité stricte (condition) : valeur_1 < valeur_2

Inférorité ou égalité (condition) : valeur_1 <= valeur_2

Supériorité stricte (condition) : valeur_1 > valeur_2

Supériorité ou égalité (condition) :valeur_1 >= valeur_2

Conversion d’un nombre décimal pour affichage avecn décimales :sprintf ( "%. nf", valeur )

A5.2.3. Connecteurs logiques

Conjonction (ET) : ( condition_1 ) and ( condition_2 )

Disjonction (OU) : ( condition_1 ) or ( condition_2 )

Négation (NON) : not ( condition )

A5.3. Tableaux

A5.3.1. Notation

Variable de type tableau :@nom

Affectation du tableau @t :@t = ( valeur_1 , valeur_2 , ... );

Elément numéron du tableau@t : $t[ n]

Position du dernier élément du tableau@t : $#t

Page 476: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

484 Perl pour les linguistes

A5.3.2. Manipulation

Ajout d’un élément à la fin du tableau @t :push ( @t, valeur );

Ajout de plusieurs éléments à la fin tableau@t :push ( @t, liste_de_valeurs );

Ajout d’un élément au début du tableau@t :unshift ( @t, valeur );

Ajout de plusieurs éléments au début du tableau@t :unshift ( @t, liste );

Copie du premier élément du tableau@tdans la variable$var et suppressionde cet élément :

$var = shift ( @t );

Construction d’une chaîne contenant les éléments du tableau @t séparés parla chaîneséparateur :

join ( séparateur , @t )

Affichage des éléments de@t, un par ligne :foreach my $element ( @t )

print $element, "\n";

Filtrage du tableau @t par une expression régulière :@resultat = grep ( / expression /, @t );

A5.3.3. Tri

Construction d’une copie triée du tableau@t :sort critère de tri @t

Pour un tri lexicographique croissant (défaut) : $a cmp $b

Pour un tri lexicographique décroissant : $b cmp $a

Pour un tri numérique croissant : $a <=> $b

Pour un tri numérique décroissant : $b <=> $a

Page 477: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Référence des principales notions de Perl 485

Pour un tri basé sur des valeurs calculées à partir des éléments :

Il suffit d’utiliser un tri lexicographique ou numérique en indiquant que l’on com-pare des valeurs calculées à partir de$a et$b en remplaçant$a et$b par des expres-sions de calcul. Exemple :

fonction( $a ) <=> fonction ( $b )

ou :

fonction( $a ) cmp fonction ( $b )

Pour plusieurs critères de tri : critère_1 or critère_2 or ...

Le deuxième critère n’est utilisé qu’en cas d’égalité suivant le premier critère, etainsi de suite.

A5.4. Hachages

A5.4.1. Notation

Variable de type hachage :%nom

Affectation du hachage%h:%h = ( clé_1 => valeur_1 , clé_2 => valeur_2 , ... );

Valeur associée à la cléchaînedans le hachage%h:$h chaîne

Lise des clés du hachage%h: keys %h

A5.4.2. Utilisation et affichage

Ajout d’un couple ( clé, valeur ) au hachage%h:$ h clé = valeur ;

Existence de la chaînechaînedans la liste des clés du hachage%h(condition) :defined ( $h chaîne )

Affichage de tous les couples (clé, valeur) du hachage%h(ordre arbitraire) :foreach my $cle ( keys %h )

print $cle, " ", $h$cle, "\n";

Page 478: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

486 Perl pour les linguistes

A5.5. Fichiers

A5.5.1. Lecture

Ouverture du fichier fichier en lecture en utilisant le descripteurFIC :open ( FIC, "<", fichier ) or die

"Problème d’ouverture de fichier : ",$!, "\n";

Lecture d’une ligne du fichier fichier et stockage dans la variable$var :$var = <FIC>;

Fermeture du fichier fichier :close FIC;

A5.5.2. Ecriture

Ouverture du fichier fichier en écriture en utilisant le descripteurFIC :open ( FIC, ">", fichier ) or die

"Problème d’ouverture de fichier : ",$!, "\n";

Ecriture d’une suite de valeurs dans le fichierfichier :print FIC valeur_1 , valeur_2 , etc.

Fermeture du fichier fichier :close FIC;

A5.5.3. Répertoires

Ouverture du répertoire répertoire utilisant le descripteur REP:opendir ( REP, répertoire ) or die

"Problème d’ouverture de répertoire : ",$!, "\n";

Lecture des noms des fichiers contenu dans le répertoirerépertoire préa-lablement ouvert en utilisant le descripteurREP, et stockage de ces noms dans letableau@fichiers :

@fichiers = readdir ( REP ) ;

Fermeture du répertoire répertoire préalablement ouvert en utilisant ledescripteur REP:

closedir ( REP );

Page 479: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Référence des principales notions de Perl 487

A5.6. Fonctions

Déclaration de la fonctionfonc :sub fonc

my $paramètre_1 = shift @_;my $paramètre_2 = shift @_;...... Calcul du résultat dans $resultat ...return $resultat;

Exécution de la fonctionfonc avec une liste de valeurs comme paramètres etrécupération du résultat dans$var :

$var = fonc ( valeur_1 , valeur_2 , ...) ;

A5.7. Variables spéciales

Message d’erreur à la suite de l’échec d’une ouverture de fichier : $!

Séparateur de flux d’entrée (défaut :\n ) : $/

Liste des arguments du programme :@ARGV

Nom du fichier contenant le programme :$0

A5.8. Syntaxe des expressions régulières

A5.8.1. Liste des métacaractères

La liste complète des métacaractères est présentée ci-dessous. Tout caractère decette liste, quand il est utilisé dans une expression régulière, doit être précédé d’unebarre oblique inverse pour interdire son interprétation entant que métacaractère.

| ( ) * + ? ^ $ . / \ [ ] -

REMARQUE.– Le tiret (-) n’est un métacaractère que dans les classes decaractères(entre crochets[ ] ). En dehors, il n’a pas de signification particulière. Toutefois,comme tout signe de ponctuation, le faire précéder d’une barre oblique inverse n’estpas néfaste.

A5.8.2. Liste des notations

L’ensemble des notations présentées dans ce chapitre sont résumées dans le tableausuivant :

Page 480: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

488 Perl pour les linguistes

Symbole Signification

* 0 ou plus occurrences+ 1 ou plus occurrences? 0 ou 1 occurrence

* ? 0 ou plusieurs occurrences, non glouton+? 1 ou plusieurs occurrences, non glouton?? 0 ou 1 occurrence, non gloutonn,m entren etmoccurrences| disjonction( ) groupement et mémorisationˆ début de chaîne$ fin de chaîne\b frontière de mot (entre\w et \W ou début ou fin de chaîne)\n fin de ligne\t tabulation. tout caractère[ ] classe de caractères[ˆ ] classe complémentaire de caractères\d tout chiffre\w toute lettre (accentuée ou non, majuscule ou minuscule), chiffre ou _\s tout caractère d’espacement\D tout caractère sauf un chiffre\W tout caractère sauf lettre, chiffre et_\S tout caractère sauf espacement\pL toute lettre\pP tout signe de ponctuation\PL tout caractère sauf une lettre

A5.8.3. Rappel de la syntaxe Perl

Mise en correspondance (expression logique) :chaîne =~ / expression / options

Négation de la correspondance (expression logique) :chaîne !~ / expression / options

Substitution (instruction) :chaîne =~ s/ expression / remplacement / options ;

Options :i ignorer les distinctions de casseg remplacement ou correspondance globale

Page 481: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Référence des principales notions de Perl 489

Variables spéciales :

$1 sous-chaîne correspondant au premier groupe mémorisé(première paire de parenthèses dans l’ordre d’ouverture)

texttt$2 sous-chaîne correspondant au deuxième groupe mémorisé(deuxième paire de parenthèses dans l’ordre d’ouverture)

...$& sous-chaîne correspondant à l’intégralité de l’expression ré-

gulière$’ sous-chaîne correspondant à la partie située à droite de$&$‘ sous-chaîne correspondant à la partie située à gauche de$&

Protection des variables dans les expressions régulières :

Placer des accolades autour des caractères constituant le nom de la variable :

$exemple

A5.8.4. Fonctions dédiées

quotemeta($chaine) retourne une copie de$chaine dans laquelle tous lescaractères qui pourraient être interprétés comme des métacaractères sont échappés.

Page 482: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

490

Page 483: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

BIBLIOGRAPHIE

[BON 03] BONAMI O., BOYÉ G., « Supplétion et classes flexionnelles »,Langages, vol. 152,p. 102-126, Armand Colin, Paris, 2003.

[BUR 02] BURKE S.M.,Perl & LWP, O’Reilly, Sébastopol, Californie, 2002.

[CHR 98] CHRISTIANSEN T., TORKINGTON N., Perl Cookbook, O’Reilly, Sébastopol, Cali-fornie, 1998.

[DRI 02] DRIX P.,XSLT Fondamental, Eyrolles, Paris, 2002.

[FRI 02] FRIEDL J.E.F.,Mastering Regular Expressions, O’Reilly, Sébastopol, Californie,2002.

[HAB 05] HABERT B., Instruments et ressources électroniques pour le français, Ophrys, Pa-ris, 2005.

[MAN 99] M ANNING C.D., SCHÜTZE H., Foundations of Statistical Natural Language Pro-cessing, MIT Press, Cambridge, Massachusetts, 1999.

[PLE 88] PLÉNAT M., « Morphologie des adjectifs en-able», Cahiers de Grammaire, vol. 13,p. 101-132, Toulouse, 1988.

[RAY 02a] RAY E.T., Introduction à XML, O’Reilly, Paris, 2002.

[RAY 02b] RAY E.T., MCINTOSH J.,Perl et XML, O’Reilly, Paris, 2002.

[SCH 06] SCHWARTZ R.L., PHOENIX T., Introduction à Perl, 4e édition, O’Reilly, Paris,2006.

[SRI 97] SRINIVASAN S., Advanced Perl Programming, O’Reilly, Sébastopol, Californie,1997.

[WAL 01] WALL L., CHRISTIANSEN T., ORWANT J., Programmation en Perl, 3e édition,O’Reilly, Paris, 2001.

491

Page 484: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

492

Page 485: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

INDEX

Symboles!= 128!~ 189" (voir guillemets)

* 166, 172

* ? 177+ 122, 172++ 144+? 177- 171-> 469, 470, 478-C (option Perl) 442-c (option Perl) 96-e (option Perl) 106-w (option Perl) 96. 122, 169–171.. (voir répertoire parent)/ 151, 174, 227/g 182, 185, 211/i 185<

en XML 317, 320inégalité 128ouverture de fichier 150redirection 98

<= 128, 144<=> 233<> (voir opérateur de lecture de ligne)= 118, 122== 128, 134=> 135=~ 173

=~s 184>

en XML 317, 320inégalité 128ouverture de fichier 153redirection 99

>= 128>>

ouverture de fichier 154redirection 99

? 172?? 177@133@ARGV156, 259@_158[ ] 170, 470# 119$ 121, 165$! 150$’ 182, 216$/ 213, 214$0 156$1 182$1 180, 182, 206, 216$2,$3,$4... (voir $1)$@198, 368$# 145$#ARGV156$& 182, 211, 216$‘ 182$a 233$b 233

493

Page 486: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

494 Perl pour les linguistes

%136& 320&$ 476&amp; 320&apos; 320&gt; 320&lt; 320&quot; 320ˆ

classe complémentaire 171critère de position 165

\ 120, 151, 168, 469\ * 477\@ 469\D 169\PL 169\S 169\W 169, 464\$ 469\% 469\b 172, 209, 211, 464\d 169\n (voir fin de ligne)\pL 169, 211\pP 169\p 403\r 396\s 169\t 203\w 169, 464\x 433 172‘ 413|

expression régulière 165pipe 101

7-Zip 1027z 53

Aabréviation 76, 290, 400ABU 36, 58, 410, 411

corpus 62lexique 64, 65, 70

accolades 136ActivePerl 85

module 104

addition 122adjectif 71adverbes 71affectation 118, 119, 125, 137

tableau 134, 223affichage 117, 118

paginé 101affixation 306affixe 302allographie 302allomorphie 302alphabet 164and 130, 209

dans une requête 372ANSI(voir CP1252)antidictionnaire 245Antiword 46apostrophes 439appel

de fonction 157système 395, 413

appendChild 351appendChild 350apprentissage 306apt (commande système) 104arbre XML 318, 339archive 38, 53

compressée 88, 102, 108de journaux 62

argument 89, 94–96, 119, 122, 155ASCII 416, 419aspirateur Web 73–75assertion 166Association des bibliophiles universels

(voir ABU)ATILF 110attribut XML 318auto-vivification 285automate à états finis 219–221, 223auxiliaire 72avertissement 98

Bbalise

fermante 317, 338HTML 358ouvrante 317, 338

Page 487: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Index 495

vide 319, 338XML 317

barre oblique arrière (voir\ )Bibliopolis 56bibliothèque (voir module)Bibliothèque universelle (voir ABU)Bibliothèque électronique duQuébec74binmode369, 434, 435, 437, 439bloc d’instructions 120, 124–126, 137,

139, 158BnF 55booléen 144boucle 124, 137–139, 143–146

arrêt 193for 143foreach 145while 137

bunzip2(commande système) 54BZIP2 53, 54

Ccaractère 40, 41

casse 38d’échappement 120de contrôle 416de fin de fichier 98non affichable 118, 416, 443police 37taille 37, 41

carriage return43, 395, 443casse 193, 464

expression régulière 174cat (commande système) 93, 101catégorie 66, 77, 202, 207

morphosyntaxique 191, 203ouverte 289, 291

catégorisation 75–77, 79, 80, 279, 412catégoriseur 107, 108catdoc(commande système) 46catégorie 203, 206CCSD 60cd (commande système) 94cellule 131, 134Centre National de Ressources Textuelles

et Lexicales (voir CNRTL)CES315césure 44

CGI 357chaîne de caractères 121

constante 118, 119extraction 261longueur 261vide 166, 399

characters346charset 367chcp (commande système) 427chemin 91, 94

absolu 91–93relatif 93, 94

cheval 115, 379chevauchement 214, 219chiffre 41, 169chomp 118, 120, 122classe de caractères 169, 170, 460Classiques des sciences sociales 58Classiques Garnier56clavier 97, 98clé 135, 146

principale 240close150, 154closedir 226, 412cmp 233, 236CNRTL 44, 56, 65, 110codage des caractères 415–455

8 bits 417en XML 317, 352incompatibilité 430

codage phonémique 286code machine 113colonne 201, 203commande 89commentaire 117, 119

en XML 322comparaison de chaînes 125compteur 143, 144concaténation 117, 119, 122, 201, 302

expression régulière 165concordance 255–268concordancier (voir concordance)condition 124–126, 144, 173conditionnelle 124–126, 134conjonction 129, 130, 209conjugaison (voir flexion)

défective 282

Page 488: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

496 Perl pour les linguistes

exceptionnelle 282connecteur logique 129consonne 171constante 121

chaîne de caractères 118, 119hachage 291tableau 131

constructionmorphologique 302, 306, 311syntagmatique 287–289, 302

conversion en texte brut 45cooccurrence 229, 238–240, 244, 249copyright37, 44, 55Cordial Analyseur77corpus 38, 39

ABU 405, 406, 411Ozkan 63, 323

correspondance 164, 173–175multiple 182, 211

CP1252421, 426CP850421, 426CPAN105CR (voir carriage return)createElement351createElement350createTextNode351createTextNode350Creative Commons 69critère

d’extraction 282de position 165de tri 201, 232

CSS322Ctrl-C 97Ctrl-D 97, 98Ctrl-Z 97, 98current_element347

Ddésambiguïsation 408, 409DATA_INDENT346DATA_MODE346dataElement346date et heure 350

localisation 457, 460décimales 253, 458, 460déclaration

de tableau 133de variable 117, 126

decode368, 438decode_entities368décompression 102, 103defined137délimiteur 118, 120, 124déplacement

de fichier 87de répertoire 87

déréférencement 279, 469dérivation 306désambiguïsation 395, 407descripteur

de fichier 147, 150de répertoire 226

dialogue 59dico 63, 70dictionnaire 38die 126, 150, 156différence

de chaîne 128numérique 128

disjonction 129, 130, 233expression régulière 165

distributeur 62Doc 45–48, 52, 59document 35

électronique 41XML 316

documentation 106DOM 339domaine public 55–57, 59, 61, 62données 86, 87Dos Latin 1(voir CP850)dossier (voir répertoire)DTD 322, 352

Eecho(commande système) 89, 90écriture

de valeurs 118, 119fichier 147, 151, 153

éditeur de texte 45Editions Acamédia 56égalité

de chaîne 128, 129

Page 489: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Index 497

numérique 128, 129élément XML 317

mixte 319racine 321

ELRA 62else125, 126, 128elsif 127, 128emptyTag 347Encode 368, 438encode438end346endTag346entête 37, 44, 117, 395, 405, 406, 411

en XML 343TEI 44, 60

entier 121entité

HTML 360, 368, 425XML 320, 343, 425

entrée standard 98environnement de travail 45, 83

Unix 85Windows 84

eq 125, 128erreur 159

de sémantique 160de syntaxe 159

Erudit 61espace 41, 169

insécable 360état (voir automate à états finis)étiquetage (voir catégorisation)étiquette (voir catégorie)C 417eval 198, 368Excel 88exception 79, 282, 399exécutable 87exit (commande système) 89, 90Explorateur Windows51, 54, 87, 91

options des dossiers 88expression booléenne 128, 209expression régulière 163–189, 196, 311

classe de caractères 169, 170correspondance 164, 173–175correspondances multiples 182, 211critères de position 165

différence de casse 174erronée 198extraction 179fermeture 166frontière de mot 177localisation 464mémorisation 179, 181, 185, 206métacaractère 168, 188, 487option 174, 182, 185optionnalité 172parenthèses 167priorité 166substitution 183, 185substitution globale 185variable 186

extension 87, 88, 411de fichier 226

extraction 179texte 405

FFAQ 106FAUX 125, 126, 144fenêtre 238, 245, 249fermeture

de fichier 147, 150expression régulière 166, 171, 172non gloutonne 177

fichier 86, 147chemin d’accès 151compression 53déplacement 87données 87écriture 147, 151, 153extension du nom 87fermeture 147, 150fin de 140lecture 147–149modification 154ouverture 91, 147, 150programme 87renommage 87suppression 87traitement 140

finaleflexionnelle 298, 302graphémique 292

Page 490: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

498 Perl pour les linguistes

fin de fichier (voir caractère de fin defichier), 140

fin de ligne 42, 118, 120, 123, 169, 212,213conversion 395

firewall (voir pare-feu)FLEMM 81flexion 114, 280, 282, 306flux 98

d’entrée standard 98, 118, 142d’erreur standard 98, 227de sortie standard 98, 118–120, 142

foire aux questions (voir FAQ)fonction 106, 119, 156–158, 235

appel 157définition 157exécution 157paramètre 158, 475prédéfinie 106, 121référence 476résultat 158, 475

for 137, 143–145, 147ForceArray380foreach 137, 145, 146format 39

binaire 87document 40GRACE 70, 71, 275, 277, 280, 283tabulé 65, 71, 77, 271texte 40, 56, 87verticalisé 75

formede citation 65de surface 203fléchie 64–66, 68polylexicale 76

fréquence 68Frantext 44, 56, 57, 62FReeBank 59, 63, 323fréquence 194, 229, 230, 236frontière de mot 172, 173, 177, 209

localisation 464

GGallica 44, 49, 56ge 128genre 44

genre grammatical 66get 364, 379, 380getAttribute 341getChildNodes342getElementsByName350getElementsByTagName341getFirstChild 341getNodeValue341Getopt::Std 106, 259, 309getopts260getopts259, 309getParentNode342glyphe 418GPL 64GRACE (voir format GRACE)grep 226, 399, 412gt 128guillemet 91, 92, 117, 120, 377

double 120, 264en XML 320

guillemet-apostrophe 421gunzip (commande système) 54GZIP 53, 54gzip (commande système) 108

Hhachage 121, 131, 135, 136, 146, 196, 230,

232anonyme 279clé 135, 146constante 291de hachages 240, 243, 244, 252, 473de tableaux 467, 471élément 135ordre des éléments 196, 232référence 470valeur 135, 136valeur arbitraire 196variable 136

HAL 60handler XML (voir récepteur XML)hapax 229hash (voir hachage)heuristique 407homographe 68homophone 68HTML 48, 49, 52, 73, 355, 357

Page 491: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Index 499

codage des caractères 425entité 360

HTML::Entities 368HTTP 356http_proxy 363

Iiconv (commande système) 431if 125, 182in_element347incrémentation 144indentation 126index 143indice 132, 134information

métatextuelle 44information mutuelle 249, 250initialisation 127, 144insertBefore351installateur 85instruction 121

de traitement XML 322interface graphique 89, 91Internet Explorer 48, 355interpolation 414interpréteur 114, 121

de commandes 89perl 90, 95

intervalle 170invite (voir prompt)ISO416ISO-8859-1(voir Latin1)ISO-8859-15(voir Latin9)ISO latin 1(voir Latin1)ISO latin 9(voir Latin9)itération (voir boucle)

Jjeu d’étiquettes 77, 79, 302

Grace 110join 201

Kkeys232, 244KOffice 48

Ll10n (voir localisation)langage de programmation 114

impératif 113interprété 87, 95, 113syntaxe 121

langue de spécialité 60lapin 115, 176La Recherche62last 193, 194, 294LATEX426Latin1419, 433Latin9420lc 193, 198, 232LC_ALL 460LC_COLLATE460LC_COLLATE464LC_CTYPE460LC_CTYPE464LC_MESSAGES460LC_NUMERIC460LC_NUMERIC464LC_TIME 460le 128lecture 117, 141

de fichier 147–149Lefff 67, 70, 71, 275, 277, 293lemmatisation 75, 77, 80, 81, 280, 302,

395, 407, 410ambiguïté 406, 407désambiguïsation 81

lemmatiseur 107lemme 65, 66, 68, 77, 80, 81, 191, 202,

203, 207, 407ambigu 407

Le Monde38, 44, 55, 59, 62Le Monde Diplomatique62length 261, 301lettre 41, 169–171

accentuée 170majuscule 193, 460minuscule 193, 291, 460

lexème 66lexique 38, 64, 66, 110, 191, 194

flexionnel 287homogénéité 275intersection 280

Page 492: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

500 Perl pour les linguistes

morphologique 65qualité 63simple 192

Lexique.org(voir Lexique3)Lexique368–70, 285, 286LGPLLR 67lib-www 363licence 37, 44, 110, 405lien hypertexte 360ligne

de commande 39, 45, 89, 90, 93, 98de texte 41, 43

line feed395, 443Linux 86, 107–109liste (voir tableau)

de mots 35littérature grise 60Live Search371, 381

clé 381inscription 381interrogation automatique 381, 383

locale (commande système) 461locale 287, 441, 462locales 427localisation 457–465localtime 350locution 67, 399log 252, 253logarithme 250, 252, 253

en base 2 253népérien 253

lt 128LWP::RobotAgent 370LWP::Simple 363, 365, 375LWP::UserAgent 365

MMac OS X 86, 107, 109MacRoman422majuscule 41marge 41marque

dérivationnelle 292flexionnelle 133, 292

maximum 268mémorisation 179, 181, 185, 206menu contextuel 87

message d’erreur 98, 100, 126, 150, 160,198, 227, 410, 460

métacaractère 165, 168, 188, 403, 487Microsoft Word88, 103minimum 301mise en page 37, 43, 44, 47, 50, 51module 104–106

ActivePerl104installateur 105installation 104paquetage 104pour XML 326

more (commande système) 101Morphalou65, 67, 70, 71, 110, 269, 271,

275, 308, 324morphophonologie 68mot 41, 44, 75, 76

grammatical 66mot-clé 121moteur de recherche 370

expression 373fréquence 385gestion des accents 373lemmatisation 373syntaxe d’interrogation 372

Mozilla Firefox 48, 355MS-ANSI(voir CP1252)MSN (voir Live Search)Multilingual Latin 1 (voir CP850)my 116, 118, 122, 127, 133

Nnavigateur Web 48, 49, 355ne 128négation 130, 208

expression régulière 189néologisme 289Netscape 355nettoyage 395new 478nom 71

commun 67, 71d’action 269propre 67, 290

nombre 66normalisation 44, 395norme de codage 41

Page 493: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Index 501

no sort 279not 130

dans une requête 372numérisation 50–52

Oobjet 477

attribut 478méthode 478

OCR 50–52ODT 48odt2txt 48œ417œuvre lexicographique 35OmniFormat52open150, 227opendir 226, 412OpenDocument Text(voir ODT)OpenOffice46–48, 103opérande 119opérateur 121

de comparaison 128de lecture de ligne 118, 122

option 74, 89, 95, 96, 106, 308, 310à valeur 259d’un programme 258, 259expression régulière 174, 182, 185initialisation 309simple 259valeur par défaut 308

optionnalité 172or 130, 150, 233

dans une requête 372oral 40ordre

lexicographique 128, 129, 199, 201,255, 441localisation 460, 464, 465

numérique 128, 129our 259, 309OUTPUT347ouverture

de fichier 147, 150, 226Ozkan (voir corpus)

Ppage Web 48, 49, 355

description 377dynamique 357statique 357

paquetage 104paragraphe 40, 42, 44, 212, 213paramètre 155

de fonction 158, 475pare-feu 362parenthésage 41parenthèses 131, 180

expression régulière 167parsefile335, 341parseur XML 326participe présent 305partition (voir volume)passage à la ligne (voirline feed)PATH84PDF 49, 50, 52, 74pdftotext 50perldoc106, 478

-i 106phrase 41pipe 101pivot 238, 241, 243, 245, 255pointeur (voir référence)police de caractères 417, 427ponctuation 41, 169, 398portée d’une variable 126POSIX 463PostScript 50ppm (commande système) 104préfixation 303–306prénom 67print 117–120, 122, 123, 144, 151, 154priorité

expression régulière 166production langagière 35programme 86, 87, 89, 114

lancement 87mise en page 121Perl 83, 84, 88, 89, 95, 96, 103

arrêt 97lancement 95

prompt 85, 89, 90, 93, 95, 98propriété Unicode 170, 291

Page 494: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

502 Perl pour les linguistes

définition 402proxy (voir serveur mandataire)ps (voir PostScript)psycholinguistique 68push200

Qquery_form 380quotemeta188, 260, 403

Rracine 86, 92, 94radical 302, 305, 307rang 236RAR 53readdir 226, 412récepteur XML 333, 338recode(commande système) 431, 432reconnaissance optique de caractères (voir

OCR)redirection 91, 98, 141

flux d’entrée standard 98flux de sortie standard 99

redistribution 55référence 468

anonyme 470, 471fonction 476tableau 469

relationdérivationnelle 306morphologique 306, 307

removeChild 351removeChild 350remplacement (voir substitution)renommage

de fichier 87de répertoire 87

répertoire 86, 226, 410affichage 87courant 93création 87déplacement 87de travail 92–94fermeture 412lecture 412parent 92, 94racine (voir racine)

renommage 87suppression 87

représentation phonologique 68, 285ressource 35, 38, 39résultat de fonction 158, 475résumé 44retour à la ligne 41, 42, (voir fin de ligne)retour chariot (voir carriage return)return 158reverse263Revues.org 61rime 285robot 369rpm (commande système) 104RTF 47, 48, 52

SSafari 355SAX332scalaire 117, 121, 128scanner 51schéma

d’affixation 306dérivationnel 302, 306, 311de suffixation 306, 308, 311flexionnel 298–300, 302, 306

SciTE 84, 102, 103script 113segmentation 75, 76, 79, 183, 395–399segmenteur 397, 399séparateur 119, 121, 397

de flux 213serveur mandataire 362setAttribute 351setHandlers335setlocale463shell 85, 89, 98–101, 105shift 158signe de ponctuation 290sleep389SOAP384SOAP::Lite 381, 384sort 201, 232, 233, 262, 277sortie standard 98sous-chaîne 175, 179sous-programme 157sous-répertoire 86

Page 495: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

Index 503

split 203–205, 209, 218, 223, 398chaînes vides 399mémorisation 398

sprintf 253, 274localisation 464

startTag 346STDERR98, 412STDIN 98, 118, 142STDOUT98, 142structuration de données 315structure

de contrôle 124, 137de données 131

complexe 471, 473sub157, 158substitution 183, 185, 302substr 261, 262, 274, 301suffixation 38, 303, 305, 306, 311suffixe 133, 307

graphémique 292suppression

de fichier 87de répertoire 87

syllabe 68système

appel 413d’exploitation 39, 86

Ttableau 131–133, 143, 145–147, 158

affectation 134, 223associatif (voir hachage)cellule 131constante 131déclaration 133de hachages 467, 473de tableaux 468élément 134, 135filtrage 226indice 132, 134référence 469taille 145variable 131, 133vide 134

tableaux parallèles 218table de fréquence 230, 231, 240tabulation 41, 169, 203, 206, 235, 443

taquet 267, 443tag-french-desamb109tag-french109TAR 53, 54tar (commande système) 53, 54TEI 44, 57, 59, 315TEL 60terminal 74, 89, 94, 97, 98TEX426texte 38, 40

brut 37segmenté 192, 194

Text Encoding Initiative(voir TEI)thèse 60TIFF 51, 52titre 37, 44toponyme 67toString 350Trésor de la langue française66trait morphosyntaxique 65, 77transcription 59transition (voir automate à états finis)tree-tagger-french(commande système)

110tree-tagger-french-desamb(commande

système) 110TreeTagger63, 77–81, 84, 107–109, 395,

406, 410, 412tri 199, 233

décroissant 233lexicographique 200, 233, 235, 258

localisation 457, 464numérique 233

tube (voir pipe)type (commande système) 101type de données 467

Uuc 193, 260Unicode320, 417, 422

format 423point de code 417, 434propriété 397, 424, 445

Unix 86, 104, 107, 109unrar (commande système) 54unrtf (commande système) 47UnxUtils 73, 84, 431

Page 496: Ludovic Tanguy, Nabil Hathout-Perl Pour Les Linguistes-Hermès (2007)

504 Perl pour les linguistes

unzip (commande système) 54URI::URL 375, 379URL 73, 74, 356url 380use122UTF-16424UTF-32423UTF-8423–426, 430, 435, 442

Vvaleur 121

booléenne 406de vérité 130indéfinie 127, 131, 136type 121

variable 121d’environnement 84dans une expression régulière 186déclaration 116, 117, 126globale 127hachage 121initialisation 127interpolation 414locale 158, 159portée 126scalaire 121spéciale 158, 179, 182, 198tableau 121, 131type 121

Verbaction69, 70, 269verbe 71

archaïque 282défectif 282

verticalisation 396vi (commande système) 104visionneuse 45volume 86, 87voyelle 170VRAI 125, 126, 139, 144

WW3C 48, 360warn 227, 301, 306, 410warning (voir avertissement)wc (commande système) 90wget 73–75while 137, 139–141, 144, 182, 193Wide character in print436, 439Windows 83–87, 91, 102, 107–109

XP 83Windows-1252(voir CP1252)word guessing291

Xx 261, 268XML 52, 57, 59, 110, 315, 351, 358

analyse 327bonne formation 321modification 347production 342traitement par flux 327, 332

XML::DOM327, 339, 342, 347, 351, 358XML::Parser 327, 333, 335, 358XML::Simple 327, 328, 331, 380XML::Writer 327, 343, 346xmlDecl 346XMLin 331, 380XMLout 384XPath353xpdf 50XSD352XSL322XSLT353

Y, ZYahoo371

identifiant 378inscription 375interrogation automatique 374

ZIP 53, 57, 88, 108