12 juillet 2023

Methodes des Expressions Rationnelles et des chaînes de caractères

Dans cet article, nous aborderons différentes méthodes qui fonctionnent en profondeur avec des expressions rationnelles (regexps).

str.match(regexp)

La méthode str.match(regexp) trouve les correspondances de l’expression rationnelle regexp dans la chaîne de texte str.

Elle dispose de 3 options :

  1. si l’expression rationnelle n’à pas de marqueur g, alors seul la première correspondance est renvoyée sous la forme d’un tableau avec le groupe capturé et ses propriétés : index (indice de la correspondance), et input (chaîne d’entrée équivalent à str):

    let str = "I love JavaScript";
    
    let result = str.match(/Java(Script)/);
    
    alert( result[0] );     // JavaScript (correspondance exacte)
    alert( result[1] );     // Script (premier groupe capturant)
    alert( result.length ); // 2
    
    // Additional information:
    alert( result.index );  // 7 (indice de la chaîne de caractère où à été trouvée la correspondance)
    alert( result.input );  // I love JavaScript (chaîne sur laquelle a été effectuée la recherche)
  2. Si la regexp dispose d’un marqueur g, alors elle retourne un tableau de toutes les correspondances de texte, sans capturer les groupes ou les autres propriétés.

    let str = "I love JavaScript";
    
    let result = str.match(/Java(Script)/g);
    
    alert( result[0] ); // JavaScript
    alert( result.length ); // 1
  3. S’il n’y a pas de correspondance, qu’il y ait un marqueur g ou non, null est renvoyé.

    C’est une nuance importante. Si il n’y a pas de correspondance, nous ne récupérons pas de tableau vide, mais null. Il n’est pas rare de faire une erreur en oubliant ce détail, e.g.:

    let str = "I love JavaScript";
    
    let result = str.match(/HTML/);
    
    alert(result); // null
    alert(result.length); // Error: Cannot read property 'length' of null

    Si nous voulons que le résultat soit un tableau, nous pouvons écrire de cette façon:

    let result = str.match(regexp) || [];

str.matchAll(regexp)

Un ajout récent
Ceci est un ajout récent au language. Les anciens navigateurs peuvent nécessiter des polyfills.

La méthode str.matchAll(regexp) est une variante “améliorée” de str.match.

Elle est principalement utilisée pour rechercher toutes les correspondances au sein de chaque groupe.

Il y a 3 différences avec match:

  1. Elle retourne un objet iterable avec les correspondances au lieu d’un tableau. Nous pouvons le transformer en un tableau classique en utilisant la méthode Array.from.
  2. Toutes les correspondances sont retournées dans un tableau incluant les groupes capturants (sous le même format que str.match sans le marqueur g).
  3. S’il n’y a aucun résultat, il renvoie un objet itérable vide au lieu de null.

Exemple d’utilisation:

let str = '<h1>Hello, world!</h1>';
let regexp = /<(.*?)>/g;

let matchAll = str.matchAll(regexp);

alert(matchAll); // [object RegExp String Iterator], pas un tableau, mais un itérateur

matchAll = Array.from(matchAll); // maintenant un tableau

let firstMatch = matchAll[0];
alert( firstMatch[0] );  // <h1>
alert( firstMatch[1] );  // h1
alert( firstMatch.index );  // 0
alert( firstMatch.input );  // <h1>Hello, world!</h1>

Si nous utilisons for..of pour boucler sur les résultats de matchAll, alors il n’est pas nécessaire d’utiliser Array.from.

str.split(regexp|substr, limit)

Divise la chaîne de caractères en utilisant la regexp (ou une sous-chaîne de caractères) comme délimiteur.

Nous pouvons utiliser split avec une chaîne de caractères comme ceci :

alert('12-34-56'.split('-')) // array of ['12', '34', '56']

Mais nous pouvons aussi diviser une chaîne de texte en utilisant une expression rationnelle:

alert('12, 34, 56'.split(/,\s*/)) // array of ['12', '34', '56']

str.search(regexp)

La méthode str.search(regexp) renvoie l’indice du premier motif correspondant, ou -1 si aucune correspondance n’est trouvée:

let str = "A drop of ink may make a million think";

alert( str.search( /ink/i ) ); // 10 (indice du premier motif correspondant)

Limitation importante: search renvoie uniquement la première correspondance.

Si nous avons besoin de l’indice ou de plus de correspondances, nous devrions utiliser d’autres méthodes, comme les trouver tous avec str.matchAll(regexp).

str.replace(str|regexp, str|func)

Il s’agit d’une méthode générique pour chercher et remplacer une chaîne de caractères, l’une des plus utiles. Le couteau suisse pour chercher et remplacer.

Nous pouvons l’utiliser sans regexps, pour chercher et remplacer une sous-chaîne de caractères: