Comprendre et implémenter les expressions régulières en Simula

Les expressions régulières (regex) sont un mécanisme puissant pour la manipulation de chaînes de caractères, offrant des capacités étendues pour la recherche, la validation et la transformation de texte. Elles sont devenues un outil essentiel dans de nombreux langages de programmation pour traiter des données textuelles de manière efficace.

Aperçu de Simula

Simula, développé dans les années 1960 par Ole-Johan Dahl et Kristen Nygaard en Norvège, est reconnu comme l'un des pionniers de la programmation orientée objet. Initialement conçu pour la simulation de processus, Simula a posé les bases conceptuelles pour des langages ultérieurs tels que C++ et Java. Bien que son utilisation soit moins répandue aujourd'hui, son influence sur la conception des langages reste significative.

Principes fondamentaux des expressions régulières

Une expression régulière est une séquence de caractères qui définit un motif de recherche. Les éléments de base incluent :

  • Littéraux : Caractères ordinaires qui correspondent à eux-mêmes (ex: "abc").
  • Classes de caractères : Définissent un ensemble de caractères possibles (ex: "[aeiou]" pour une voyelle).
  • Séquences spéciales : Représentent des types de caractères courants (ex: "\\d" pour un chiffre, "\\s" pour un espace blanc, "\\w" pour un caractère alphanumérique).
  • Quantificateurs : Spécifient la fréquence d'occurrence d'un élément (ex: "a*" pour zéro ou plusieurs 'a', "a+" pour une ou plusieurs 'a', "a?" pour zéro ou une 'a').
  • Groupes : Utilisent des parenthèses pour capturer des sous-expressions (ex: "(ab)+").
  • Ancres : Indiquent des positions spécifiques dans la chaîne (ex: "^" pour le début de la ligne, "$" pour la fin de la ligne).

Implémentation des expressions régulières en Simula

Simula ne possède pas de fonctionnalités regex intégrées nativement. Leur utilisation nécessite généralement l'importation de bibliothèques externes ou la création de classes personnalisées. Voici une approche pour modéliser des fonctionnalités de base d'expressions régulières.

Conception d'une classe RegexMatcher

Nous pouvons créer une classe pour encapsuler le motif et les opérations de recherche.

CLASS RegexMatcher;
 DEFINE PROTECTED pattern STRING;
 DEFINE PUBLIC PROCEDURE Initialize(pat STRING);
   pattern := pat;
 END;
 DEFINE PUBLIC FUNCTION Matches(text STRING) BOOLEAN;
   ! Implémentation de la logique de correspondance complète;
 END;
 DEFINE PUBLIC FUNCTION Search(text STRING) ARRAY OF INTEGER;
   ! Implémentation de la recherche de sous-chaînes correspondantes;
 END;
 DEFINE PUBLIC FUNCTION Substitute(text STRING, replacement STRING) STRING;
   ! Implémentation du remplacement des correspondances;
 END;
END CLASS RegexMatcher;

Logique de correspondance simple (Exemple simplifié)

Une fonction de correspondance basique pourrait itérer sur la chaîne et vérifier les occurrences du motif. Notez que ceci est une simplification et ne gère pas toutes les complexités des regex.

BOOLEAN PROCEDURE RegexMatcher.Matches(text STRING);
 BEGIN
   INTEGER textLen, patternLen;
   INTEGER i, j;
   textLen := LENGTH(text);
   patternLen := LENGTH(pattern);

   IF patternLen = 0 THEN RETURN TRUE;
   IF textLen < patternLen THEN RETURN FALSE;

   FOR i := 1 TO textLen - patternLen + 1 DO
   BEGIN
     j := 1;
     WHILE (j <= patternLen AND SUBSTR(text, i + j - 1, 1) = SUBSTR(pattern, j, 1)) DO
       j := j + 1;
     END;
     IF (j > patternLen) THEN RETURN TRUE;
   END;
   RETURN FALSE;
 END;

Fonction de recherche (Exemple simplifié)

Pour trouver toutes les occcurrences, on peut adapter la logique de correspondance.

ARRAY OF INTEGER PROCEDURE RegexMatcher.Search(text STRING);
 BEGIN
   INTEGER textLen, patternLen;
   INTEGER i, j;
   INTEGER positions[100]; ! Taille fixe pour l'exemple;
   INTEGER count;

   textLen := LENGTH(text);
   patternLen := LENGTH(pattern);
   count := 0;

   IF patternLen = 0 OR textLen < patternLen THEN RETURN positions[1:0]; ! Retourne un tableau vide;

   FOR i := 1 TO textLen - patternLen + 1 DO
   BEGIN
     j := 1;
     WHILE (j <= patternLen AND SUBSTR(text, i + j - 1, 1) = SUBSTR(pattern, j, 1)) DO
       j := j + 1;
     END;
     IF (j > patternLen) THEN
     BEGIN
       count := count + 1;
       positions[count] := i;
     END;
   END;
   RETURN positions[1:count];
 END;

Fonction de remplacement (Exemple simplifié)

Le remplacement nécessite de reconstruire la chaîne en utilisant les positions trouvées.

STRING PROCEDURE RegexMatcher.Substitute(text STRING, replacement STRING);
 BEGIN
   STRING result;
   INTEGER i, lastPos;
   ARRAY OF INTEGER foundIndices;

   result := "";
   lastPos := 1;
   foundIndices := Search(text);
   patternLen := LENGTH(pattern);

   FOR i := LOWERBOUND(foundIndices, 1) TO UPPERBOUND(foundIndices, 1) DO
   BEGIN
     result := result & SUBSTR(text, lastPos, foundIndices[i] - lastPos);
     result := result & replacement;
     lastPos := foundIndices[i] + patternLen;
   END;

   result := result & SUBSTR(text, lastPos);
   RETURN result;
 END;

Exemple d'utilisation

INTEGER PROCEDURE Main;
 BEGIN
   STRING sampleText;
   RegexMatcher myMatcher;

   sampleText := "Simula is a foundational object-oriented language. Learn Simula.";
   myMatcher.Initialize("Simula");

   IF myMatcher.Matches(sampleText) THEN
     OutText("The entire text matches the pattern." & CHAR(13) & CHAR(10))
   ELSE
     OutText("The entire text does not match the pattern." & CHAR(13) & CHAR(10));

   OutText("Searching for occurrences..." & CHAR(13) & CHAR(10));
   INTEGER array indices;
   indices := myMatcher.Search(sampleText);
   FOR i := LOWERBOUND(indices, 1) TO UPPERBOUND(indices, 1) DO
     OutText("Found at index: " & INTEGER STRING(indices[i]) & CHAR(13) & CHAR(10));

   STRING newText;
   newText := myMatcher.Substitute(sampleText, "Simula-like");
   OutText("Text after substitution: " & newText & CHAR(13) & CHAR(10));

   RETURN 0;
 END;

Applications courentes des expressions régulières

  • Validation de données : Assurer que les entrées utilisateur (e-mails, numéros de téléphone, codes postaux) respectent un format spécifique. Exemple de motif pour un email simple : "^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$".
  • Extraction d'informations : Récupérer des données strcuturées à partir de textes non structurés, comme des adresses IP, des dates, des montants monétaires à partir de logs ou de documents. Exemple pour une adresse IP : "\\b(?:\\d{1,3}\\.){3}\\d{1,3}\\b".
  • Nettoyage et transformation de texte : Supprimer des caractères indésirables, normaliser des formats, remplacer des éléments répétitifs. Exemple pour supprimer les espaces multiples : "\\s+" remplacé par " ".

Étiquettes: Simula Expressions Régulières manipulation de chaînes Programmation orientée objet

Publié le 6 octobre à 17h44