Rechercher et remplacer

Parent Previous Next



Rechercher et remplacer



Une fonctionnalité intéressante des regex est de pouvoir effectuer des « rechercher-remplacer ». Rechercher-remplacer signifie qu'on recherche des portions de texte dans une chaîne de caractères et qu'on remplace ces portions par d'autres. C'est relativement pratique pour modifier une chaîne rapidement, ou pour convertir des données. Une utilisation fréquente est la conversion de balises BBCode en HTML pour prévisualiser le contenu d'une zone de texte.

Un rechercher-remplacer se fait au moyen de la méthode replace() de l'objet String. Elle reçoit deux arguments : la regex et une chaîne de caractères qui sera le texte de remplacement. Petit exemple :

var sentence = 'Je m\'appelle Sébastien';

 

var result = sentence.replace(/Sébastien/, 'Johann');

 

alert(result); // Affiche : « Je m'appelle Johann »


Très simple : replace() va rechercher le prénom « Sébastien » et le remplacer par « Johann ».


Utilisation de replace() sans regex


À la place d'une regex, il est aussi possible de fournir une simple chaîne de caractères. C'est utile pour remplacer un mot ou un groupe de mots, mais ce n'est pas une utilisation fréquente, on utilisera généralement une regex. Voici toutefois un exemple :

var result = 'Je m\'appelle Sébastien'.replace('Sébastien', 'Johann');

 

alert(result); // Affiche : « Je m'appelle Johann »


L'option g


Nous avions vu l'option i qui permet aux regex d'être insensibles à la casse des caractères. Il existe une autre option, g, qui signifie « rechercher plusieurs fois ». Par défaut, la regex donnée précédemment ne sera exécutée qu'une fois : dès que « Sébastien » sera trouvé, il sera remplacé… et puis c'est tout. Donc si le prénom « Sébastien » est présent deux fois, seul le premier sera remplacé. Pour éviter ça, on utilisera l'option g qui va dire de continuer la recherche jusqu'à ce que plus rien ne soit trouvé :

var sentence = 'Il s\'appelle Sébastien. Sébastien écrit un tutoriel.';

 

var result = sentence.replace(/Sébastien/g, 'Johann');

 

alert(result); // Il s'appelle Johann. Johann écrit un tutoriel.


Ainsi, toutes les occurrences de « Sébastien » sont correctement remplacées par « Johann ». Le mot occurrence est nouveau ici, et il est maintenant temps de l'employer. À chaque fois que la regex trouve la portion de texte qu'elle recherche, on parle d'occurrence. Dans le code précédent, deux occurrences de « Sébastien » sont trouvées : une juste après « appelle » et l'autre après le premier point.


Rechercher et capturer


Il est possible d'utiliser les parenthèses capturantes pour extraire des informations et les réutiliser au sein de la chaîne de remplacement. Par exemple, nous avons une date au format américain : 05/26/2011, et nous souhaitons la convertir au format jour/mois/année. Rien de plus simple :

var date = '05/26/2011';

 

date = date.replace(/^(\d{2})\/(\d{2})\/(\d{4})$/, 'Le $2/$1/$3');

 

alert(date); // Le 26/05/2011


Chaque nombre est capturé avec une parenthèse, et pour récupérer chaque parenthèse, il suffit d'utiliser$1$2 et $3 (directement dans la chaîne de caractères), exactement comme nous l'aurions fait avecRegExp.$1.


Et si on veut juste remplacer un caractère par le signe dollar, il faut l'échapper ?


Pour placer un simple caractère $ dans la chaîne de remplacement, il suffit de le doubler, comme ceci :

var total = 'J\'ai 25 dollars en liquide.';

 

alert(total.replace(/dollars?/, '$$'); // J'ai 25 $ en liquide


Le mot « dollars » est effectivement remplacé par son symbole. Un point d'interrogation a été placé après le « s » pour pouvoir trouver soit « dollars » soit « dollar ».


Voici un autre exemple illustrant ce principe. L'idée ici est de convertir une balise BBCode de mise en gras ([b]un peu de texte[/b]) en un formatage HTML de ce type : <strong>un peu de texte</strong>. N'oubliez pas d'échapper les crochets qui sont, pour rappel, des métacaractères !

var text = 'bla bla [b]un peu de texte[/b] bla [b]bla bla en gras[/b] bla bla';

 

text = text.replace(/\[b\]([\s\S]*?)\[\/b\]/g, '<strong>$1</strong>');

 

alert(text);


Mais pourquoi avoir utilisé [\s\S] et non pas juste le point ?


Il s'agit ici de trouver tous les caractères qui se trouvent entre les balises. Or, le point ne trouve que des caractères et des espaces blanc hormis le retour à la ligne. C'est la raison pour laquelle on utilisera souvent la classe comprenant \s et \S quand il s'agira de trouver du texte comportant des retours à la ligne.


Cette petite regex de remplacement est la base d'un système de prévisualisation du BBCode. Il suffit d'écrire une regex de ce type pour chaque balise, et le tour est joué :

<script>

 

function preview() {

    var value = document.getElementById("text").value;

     

    value = value.replace(/\[b\]([\s\S]*?)\[\/b\]/g, '<strong>$1</strong>'); // Gras

    value = value.replace(/\[i\]([\s\S]*?)\[\/i\]/g, '<em>$1</em>'); // Italique

    value = value.replace(/\[s\]([\s\S]*?)\[\/s\]/g, '<del>$1</del>'); // Barré

    value = value.replace(/\[u\]([\s\S]*?)\[\/u\]/g, '<span style="text-decoration: underline">$1</span>'); // Souligné

     

    document.getElementById("output").innerHTML = value;

}

 

</script>

 

<form>

    <textarea id="text"></textarea><br />

    <button type="button" onclick="preview()">Prévisualiser</button>

    <div id="output"></div>

</form>



Utiliser une fonction pour le remplacement


À la place d'une chaîne de caractères, il est possible d'utiliser une fonction pour gérer le ou les remplacements. Cela permet, par exemple, de réaliser des opérations sur les portions capturées ($1$2,$3…).


Les paramètres de la fonction sont soumis à une petite règle, car ils doivent respecter un certain ordre (mais leurs noms peuvent bien évidemment varier) : function(str, p1, p2, p3 /* ... */, offset, s). Les paramètres p1p2p3… représentent les fameux $1$2$3... S'il n'y a que trois parenthèses capturantes, il n'y aura que trois « p ». S'il y en a cinq, il y aura cinq « p ». Voici les explications des paramètres :


Si on n'a besoin que de p1 et de p2 et pas des deux derniers paramètres, ces deux derniers peuvent être omis.


Pour illustrer cela, nous allons réaliser un petit script tout simple, qui recherchera des nombres dans une chaîne et les transformera en toutes lettres. La transformation se fera au moyen de de la fonctionnum2Letters() qui a été codée lors du tout premier TP : Convertir un nombre en toutes lettres.

var sentence = 'Dans 22 jours, j\'aurai 24 ans';

 

var result = sentence.replace(/(\d+)/g, function(str, p1) {

    p1 = parseInt(p1);

 

    if (!isNaN(p1)) {

        return num2Letters(p1);

    }   

});

 

alert(result); // Affiche : « Dans vingt-deux jours, j'aurai vingt-quatre ans »


L'exemple utilise une fonction anonyme, mais il est bien évidemment possible de déclarer une fonction :

function convertNumbers(str) {

    str = parseInt(str);

 

    if (!isNaN(str)) {

        return num2Letters(str);

    }   

}

 

var sentence = 'Dans 22 jours, j\'aurai 24 ans';

 

var result = sentence.replace(/(\d+)/g, convertNumbers);



Créé avec HelpNDoc Personal Edition: Générateur de documentation iPhone gratuit

Site à deux balles