Processing – 2. Strings( )

A Mile of String, Marcel Duchamp, 1942

Afin de travailler avec du texte, nous allons utiliser des variables de type String. Le tutoriel de Douglas, Les variables, est une très bonne introduction. Mais voici quelques lignes pour se rappeler. Il existe deux catégories de variables, des variables primitives et des variables composites. Par exemple, int, float, et boolean sont des variables primitives qui ne servent que pour contenir une valeur qui peut varier. Elles sont identifiables par le fait que leur nom commence par une lettre minuscule.

Une variable de type String est une variable composite, identifiée comme tel par le majuscule. Des variables composites contiennent une ou plusieurs valeurs (du texte dans le cas de String) mais aussi des méthodes pour opérer sur ce contenu. Tiens ça me rappelle quelque chose… On verra plus tard qu’elles sont en fait des Objets, des sortes de mini-programmes qui englobent à la fois des propriétés (des variables internes qui s’appellent dans la documentation des fields) et leurs propres méthodes. On y reviendra.

Mais pour l’instant on va considérer un String comme un conteneur de texte qui nous donne aussi les moyens de le modifier. Ou comme dit la documentation, “un String est une séquence de caractères. La classe String comprend des méthodes pour examiner des caractères individuelles, pour la comparaison de deux Strings, la recherche à l’intérieur d’un String, l’extraction d’une partie, et la conversion vers des minuscules ou majuscules.” Par exemple :

String mon_texte;

void setup() {
  mon_texte = "Ceci est un petit texte qui est très court.";
  println(mon_texte);
}

Résultat -

Ceci est un petit texte qui est très court.

Comme pour toutes les variables, si on déclare une variable String en dehors des méthodes setup() et draw() elle a une portée globale et du coup est donc disponible (on peut l’intérroger ou la modifier) depuis toutes les méthodes, même celles de notre création. Ici, on lui assigne une valeur dans setup() avec :

mon_texte = "Ceci est un petit texte qui est très court.";

Si on regarde la page de référence Processing sur les Strings on voit ceci :

Cette liste représente une partie des méthodes appartenant à toutes les variables de type String. Il faut rappeler que Processing est un langage et un environnement de développement qui est, en réalité, une version simplifiée du langage de programmation Java, conçue afin de permettre à des non-programmeurs d’apprendre la programmation. Mais en même temps toute la fonctionnalité de Java, et c’est énorme, est disponible dans nos projets Processing si on sait comment y accéder. On verra cela d’ici peu.

3 Stoppages étalon, Marcel Duchamp, 1913–14, collection du MoMA

Les Méthodes
Comment utilise-t-on ces méthodes? On s’en sert avec ce qui s’appelle du dot-syntax. Par exemple, si on aimerait savoir la longeur de notre String, on pourrait la déterminer avec la méthode .length() en l’appelant ainsi -

Ce qui nous donne 43. Pour résumer, afin d’appeler une méthode d’une variable composite (autrement dit un Objet) il suffit de mettre la variable suivie d’un point (le “dot”), le nom de la méthode et des parenthèses qui contiendraient des arguments (on dit aussi des paramètres) à envoyer à la méthode (vide en l’occurence). Tiens, ça me rappelle encore quelque chose… Il nous donne le nombre de caractères, y compris les espaces et la ponctuation.

Avec ce qu’on a appris dans le tutoriel précédent, on pourrait imaginer une méthode en pseudocode, une description en langage courant qui permet de visualiser le fonctionnement d’un vrai code, qui pourrait être à l’intérieur des objets de type String.

int length() {
  int maLongeur;
 
  Compter le nombre de caractères du texte
  Mettre ce chiffre dans maLongeur;
 
  return maLongeur;
}

Ce code ne fonctionnerait pas, mais il nous permet de mieux comprendre qu’elle rendrait une valeur de type int après avoir effectuer des opérations sur son texte. Effectivement, il existe une vraie méthode avec des transformations à la place de notre pseudocode qui n’est pas très éloigné de ceci. Maintenant qu’on sait comment ça marche on pourrait essayer d’autres méthodes en sachant que c’est dans leurs combinaisons qu’on va pouvoir analyser et manipuler un texte.

.indexOf()
Par exemple, si on veut trouver la première occurence du mot “un” dans mon_texte on peut faire ceci -

String mon_texte;
 
void setup() {
  mon_texte = "Ceci est un petit texte qui est très court."; 
 
  int in = mon_texte.indexOf("un");
  println(in);
}

Ce qui donne la valeur 9. Pourquoi pas 10? String, tout comme Array, considère la premier emplacement comme la place 0 (occupé par le “C”) et la deuxième place est la position 1 (occupé par le ‘”e”) et ainsi de suite. Ici, il donne 9, qui est la position de la première lettre de “un” (le “n” est à la place 10). Par contre si on demand -

int in = mon_texte.indexOf("hello");

Il rend la valeur -1 qui correspond à “pas trouvé”. Il faut savoir si on demand -

int in = mon_texte.indexOf("ci");

Il rend la valeur 2, montrant qu’il ne prend pas en considération des mots individuels mais plutôt le String en entier comme une seule chaîne de caractères.

.substring()
Maintenant si on voudrait récuperer une partie de notre variable, disons la partie qui commence avec “un”, on pourrait faire ceci -

String mon_texte;
 
void setup() {
  mon_texte = "Ceci est un petit texte qui est très court."; 
 
  int in = mon_texte.indexOf("un");
  println(in);
 
  println(mon_texte.substring(in));
}

Résultat -

un petit texte qui est très court.

Utiliser ainsi .substring() rend le texte à partir d’une position, ici 9. Cette méthode nécessite un argument (le chiffre qui est envoyé entre les paranthèses) qui est de type int. A l’intérieur des variables de type String il existe une méthode qui, en pseudocode, ressemblerait à quelque chose comme -

String substring(int aPartirDe) {
 
String texteTemp;
 
  Créer un extrait de ce texte, du caractère qui occupe la place aPartirDe
  et qui contient tous les caractères après;
 
  Met ce texte dans la variable locale texteTemp;
 
  return texteTemp;
}

Notons, que ce code ne fonctionnerait pas non plus, c’est encore du pseudocode. Mais on pourrait imaginer que le String qui est à la place du void habituel, permet de rendre, en lien avec return, un autre String transformé.

Il faut savoir qu’il est aussi possible de lui donner un début et une fin, c’est-à-dire, deux arguments. Si on rajoute cette ligne de code à l’exemple précédent -

println(mon_texte.substring(in, in + 14));  // pour mémoire in = 9

Résultat -

un petit texte

Si on est attentif on voit qu’étant donné que in = 9, on a 9 + 14 = 23. Et si on commence juste après la position 9 et on rajoute 14 places, on devrait tomber sur l’espace après le mot texte – “un petit texte_”. Dans la documentation de .substring() on découvre que si on utilise la version .substring(début, fin) le résultat est un string entre début et fin – 1. Pour obtenir juste le “un”, on aurait besoin de .substring(in, in + 2) qui donnerait le texte aux positions 9 et 10.

.toUpperCase(), .toLowerCase()
Ces deux méthodes transforment le String en majuscules ou en minuscules.

println(mon_texte.toUpperCase());

Résultat -

CECI EST UN PETIT TEXTE QUI EST TRÈS COURT.

Si on voudrait mettre un majuscule sur la première lettre de notre substring “un petit texte qui est très court.” on pourrait combiner des méthodes -

String mon_texte, texte2;
 
void setup() {
  mon_texte = "Ceci est un petit texte qui est très court."; 
 
  int in = mon_texte.indexOf("un");
 
  texte2 = mon_texte.substring(in);
 
  texte2 = texte2.substring(0, 1).toUpperCase() + texte2.substring(1);
 
  println(texte2);
}

Résultat -

Un petit texte qui est très court.

Notons pour obtenir uniquement le texte à la position 0 du texte2, le “u”, on utilise texte2.substring(0, 1). début = 0 et fin = 1 – 1 ou 0, qui permet d’avoir juste le texte à la position 0.

La Concaténation
Dans l’exemple précédent, substring(0, 1) correspond à la première lettre et substring(1) au reste du texte à partir de la deuxième lettre (position 1). Il formule une nouvelle chaîne de caractères en utilisant ce qui s’appelle la concaténation. On l’a vu dans le premier tutoriel. Sur Wikipedia on pourrait lire, “En programmation, on appelle la concaténation de deux chaînes de caractères, la chaîne formée de ces deux chaînes mises bout à bout.” Ici, on prend la première lettre et on le transforme en majuscule. Puis, on récupère le texte à partir de la deuxième lettre. Ensuite, on les met bout à bout et on insert cette nouvelle chaîne à l’intérieur de la variable d’origine, remplaçant son contenu.

La concaténation de Strings avec des variables de type int ou float transforme automatiquement ces derniers en String.

  int num = 5;
  String un_texte = "J'ai vu ce film " + num + " fois";
  println(un_texte);

Ceci donne le String “J’ai vu ce film 5 fois”, où le 5 est devenu du texte comme les autres caractères de la chaîne. Un des usages fréquent de la concaténation est la construction de noms de fichiers externes à la volée. Comme dans l’exemple de Douglas dans le tutoriel listes.

  for(int i = 0; i < 10; i++) {
    images[i] = loadImage("marey_" + i + ".gif");
  }

La mine d’or
Plus haut, on avait parlé du fait que Processing est conçu, en quelque sorte, sur le dos de Java. Toute la fonctionnalité de celui-ci est accessible si on sait s’y retrouver dans la documentation, les javadocs. A priori, tout langage de programmation a un Application Programming Interface (API) qui est sa référence. Il détaille tous ses objets (et leurs méthodes) ainsi que la syntaxe pour les utiliser. Vous connaissez celui de Processing. Maintenant, jetons un coup d’oeil sur l’API de Java.

En bas à gauche, on peut voir toutes les Classes Java de base. En haut à gauches les mêmes Classes sont repertoriées par package, des familles de Classes (qui ont des fonctionnalités complémentaires). Dans la référence Processing, on peut lire, “une classe est un composite de données et de méthodes (functions) qui pourrait être instancié en tant qu’objet.” Autrement dit, une classe est comme une matrice, un template, qui permet de générer des objets de ce type. Par exemple, créer une variable de type String veut dire, créer un objet à partir de la classe String. Cet objet possèderait toute la fonctionalité de la classe, et peut donc contenir du texte et opérer sur ce texte avec des méthodes appartenant à cette classe.

Si on regarde dans l’API Java pour String (trouver dans la partie en bas à gauche, cliquer dessus) on voit dans la partie “Method Summary”, toutes les méthodes qui sont dans la documentation Processing, ainsi que pleine d’autres.

.replaceAll()
Pour comprendre comment utiliser des méthodes Java, on va regarder une méthode qui est bien utile, .replaceAll(), qui permet à remplacer toutes les instances d’un mot par un autre.

Si on regarde dans la colonne à gauche on voit String. C’est le type de valeur que rend la méthode en sortie (ce n’est pas void). Après on voit, replaceAll(String regex, String replacement). Ce qui est entre les parenthèses, sont le type et le nombre de données qu’on lui envoie, ses entrées. Il y en a deux. Le premier argument est la chose à remplacer, le deuxième le nouveau mot (ou chaîne de caractères). Mais c’est quoi un regular expression??? On y reviendra. Mais pour l’instant il faut penser qu’on peut y mettre un String. Par exemple -

String mon_texte, texte2;
 
void setup() {
 
  mon_texte = "La programmation est vraiment trop obscure."; 
 
  texte2 = mon_texte.replaceAll("obscure", "cool");
 
  println(texte2);
}

Résultat -

La programmation est vraiment trop cool.

On pourrait imaginer pas mal de projets à base de ce principe. Un projet qui se servait de cette logique de remplacement était Tha Shizzolator de Snoop Dogg (malheureusement plus en ligne) qui traduisait des pages web dans un style qui lui est propre. Gizoogle est une idée similaire.

Pour aller plus loin on pourrait utiliser des regular expressions qui sont, selon Wikipedia, composé d’ “une chaine de caractères dont le motif décrit un ensemble de chaînes de caractères selon une syntaxe précise.” C’est, en quelque sorte, un petit lexique qui permet de trouver des patterns dans un texte. On y reviendrai peut-être dans un autre tutoriel mais pour donner un exemple, on pourrait écrire “\\d” comme premier argument de replaceAll(String regex, String replacement). “\\d” est un regular expression (regex) qui veut dire un chiffre de 0 à 9.

String mon_texte, texte2;
 
void setup() {
 
  mon_texte = "Le mot de passe est 95675."; 
 
  texte2 = mon_texte.replaceAll("\\d", "*");
 
  println(texte2);
}

Résultat – “Le mot de passe est *****.”

Un des excellents tutoriels de Daniel Shiffman est sur les regular expressions. Après avoir lu mes tutoriels d’introduction au traitement de texte, je vous conseille les siens, qui permettent de vraiment approfondir les notions de base élaborées ici.

Jeff Guess (dérnière mise à jour oct 2010)

Comments are closed.