Français

Texte et outils quotidiens · Boîte à outils de texte

De Kleene à JavaScript : une brève histoire des expressions régulières

· Contexte

expressions régulières javascript historique informatique

Une chronologie reliant les automates finis, les expressions régulières Unix grep, Perl et JavaScript
Illustration vectorielle originale de ToolAcre

Retrace les expressions régulières de la théorie des automates des années 1950 en passant par ed, grep et Perl jusqu'à la saveur JavaScript dans chaque navigateur, expliquant pourquoi la syntaxe ressemble à ce qu'elle est et quelles fonctionnalités sont arrivées quand.

L'étrange petit langage que tout le monde connaît à moitié : pourquoi la syntaxe des regex semble ancienne et incohérente

Les expressions régulières ressemblent à un langage assemblé à travers les époques, car c'est essentiellement ce qu'elles sont. Un noyau compact d'alternance, de répétition et de regroupement est passé de la notation mathématique aux commandes de l'éditeur, aux filtres de ligne de commande et aux fonctionnalités du langage de programmation. La ponctuation a survécu tandis que chaque hôte a ajouté ses propres commodités, contraintes et terminologie.

Cet historique explique pourquoi un modèle peut sembler familier mais se comporter différemment entre grep, Perl, Python et JavaScript. « Regex » est un nom de famille, pas une grammaire universelle. Pour un analyste autodidacte, la leçon utile n'est pas de mémoriser tous les dialectes, mais d'identifier le moteur, les drapeaux et les règles de remplacement avant de se fier à un modèle emprunté.

Les événements réguliers de Kleene — les mathématiques des automates finis des années 1950 qui nous ont donné l'étoile

Les travaux de Stephen Cole Kleene sur les automates finis et les « événements réguliers » ont fourni la racine théorique au cours des années 1950. Sa notation décrivait des ensembles de séquences de symboles utilisant des opérations telles que l'union, la concaténation et la fermeture. L'opération de fermeture est devenue l'étoile Kleene : `A*` signifie zéro ou plusieurs répétitions tirées de A, et pas simplement « répéter une ou plusieurs fois ».

Les langages formels réguliers reconnus par les automates finis sont plus restreints que de nombreuses constructions désormais vendues sous l'étiquette regex. Les références arrière, par exemple, peuvent exprimer des conditions au-delà de ce modèle classique. Les moteurs modernes préservent donc le nom historique et une grande partie de la notation tout en implémentant des langages de modèles dont les capacités et les stratégies d’exécution s’étendent au-delà de l’objet mathématique original de Kleene.

Thompson, ed et grep — comment l'expression régulière est entrée dans l'édition de texte à la fin des années 1960 et au début des années 1970, dans les outils Unix

Ken Thompson a relié la théorie aux outils de travail textuels. Son article 1968 Communications of the ACM décrivait la compilation d'expressions régulières dans du code machine pour la recherche de texte, et ses précédents travaux d'éditeur ont aidé à placer la correspondance de modèles dans la lignée Unix. L'éditeur `ed` utilisait des expressions régulières dans les commandes qui sélectionnaient et transformaient les lignes correspondantes.

Le nom `grep` provient d'une commande `ed` communément rendue par `g/re/p` : sélectionnez globalement les lignes correspondant à une expression régulière et imprimez-les. Les premiers grep n'étaient pas la collection d'options GNU d'aujourd'hui, et les formulaires POSIX de base et étendus ultérieurs diffèrent. Le changement durable était pratique : un petit langage symbolique est devenu une interface quotidienne pour trouver du texte.

Perl et PCRE — les extensions qui ont ajouté des quantificateurs non gourmands, une recherche et la syntaxe que la plupart des outils copient aujourd'hui

Perl a créé un langage de modèles plus riche, central à la programmation générale. Dans toutes ses versions, les programmeurs ont rencontré des groupes de capture, des références arrière, des assertions, des quantificateurs paresseux et des modificateurs de modèles dans un écosystème très visible. La documentation Perl 5 enregistre des constructions telles que `*?` pour une correspondance minimale et `(?=...)` pour une anticipation positive, ainsi que de nombreuses fonctionnalités absentes des anciens formulaires Unix.

Il est plus sûr de dire que Perl a popularisé ce style plutôt que de lui attribuer le mérite d'avoir inventé toutes les extensions. PCRE proposait délibérément une syntaxe compatible avec Perl, tandis que d'autres moteurs adoptaient certaines idées et en rejetaient d'autres. La ponctuation partagée peut masquer différentes sémantiques, comportements ou performances Unicode. « Semblable à Perl » décrit par conséquent une large influence, et non une garantie qu'un modèle Perl est portable.

Perl a popularisé un langage de modèles pratique plus vaste ; moteurs ultérieurs empruntés de manière sélective

JavaScript a standardisé ses propres objets `RegExp` et sa syntaxe littérale, telle que `/pattern/gi`, pour les programmes exécutés dans les navigateurs et autres environnements ECMAScript. Sa saveur comprend des groupes de capture et de non-capture, des références arrière, une anticipation, des quantificateurs paresseux et des classes de caractères. Les éditions ultérieures ont ajouté des groupes de capture nommés et des assertions lookbehind dans la spécification ES2018.

JavaScript n'est pas PCRE ou Python avec des délimiteurs différents. La disponibilité des fonctionnalités dépend de l'édition ECMAScript implémentée par le moteur, et les indicateurs font partie du comportement plutôt que de la décoration. Le guide des expressions régulières de MDN est la référence pratique pertinente pour la syntaxe du navigateur, mais même des exemples JavaScript valides peuvent s'appuyer sur des indicateurs qu'une interface particulière n'expose pas.

JavaScript a gagné des groupes nommés et un lookbehind dans ES2018, mais les moteurs et les indicateurs diffèrent toujours

Les navigateurs placent un moteur d'expression régulière JavaScript à proximité du travail de texte ordinaire. Une page peut compiler un modèle, compter les correspondances et le transmettre à `String.prototype.replace` sans envoyer le texte à un service regex spécialisé. Cette disponibilité rend possible une interface de recherche et de remplacement côté navigateur, bien que la page environnante doive toujours être inspectée séparément pour des réclamations plus larges en matière de confidentialité.

L'implémentation de ToolAcre appelle `new RegExp` à l'intérieur de `compilePattern`, détecte les échecs de compilation et renvoie une erreur au lieu de lancer. `findReplace` compte les correspondances avant d'appliquer l'opération de remplacement standard. Par conséquent, les jetons de remplacement JavaScript tels que les références de capture suivent l'API de chaîne hôte ; la syntaxe regex et la syntaxe de remplacement sont des langages liés mais distincts.

Ce que cela ne couvre pas : la théorie du langage formel au-delà des bases et des performances internes du moteur

Ce court historique ne prouve pas l'équivalence entre les moteurs pratiques et les automates finis, n'étudie pas les algorithmes d'exécution des regex ou ne classe pas les implémentations par vitesse. Le retour en arrière, les techniques de temps linéaire et les schémas pathologiques méritent un traitement séparé. La protection ToolAcre détecte les erreurs de syntaxe, mais elle ne détecte pas une expression valide qui effectue un retour en arrière excessif et bloque le thread principal du navigateur.

La chronologie n'attribue pas non plus chaque métacaractère à un seul inventeur. Les fonctionnalités logicielles sont souvent arrivées via des articles, des éditeurs, des versions linguistiques et des réimplémentations compatibles plutôt que par un transfert propre. Les sources prennent en charge des jalons spécifiques ; ils ne justifient pas l’histoire plus simple selon laquelle un produit a créé en gros des regex modernes ou que des saveurs ultérieures ont hérité d’un comportement identique.

Ce qu'il faut retenir : le mode regex de Text Toolkit est la version JavaScript, donc les modèles de la documentation du navigateur fonctionnent comme écrit.

L'héritage pratique est visible dans ToolAcre : activez Regex et le texte de recherche est compilé par le moteur JavaScript du navigateur. Laissez Regex désactivé et les métacaractères sont échappés, ce qui rend la recherche littérale. Le mot entier enveloppe l'expression avec des limites `` de style ASCII, tandis que le respect de la casse contrôle si l'indicateur `i` accompagne l'indicateur global `g` toujours présent.

Ce dernier détail corrige la large promesse du plan selon laquelle les modèles de documentation du navigateur fonctionnent tels qu'ils sont écrits. ToolAcre n'expose pas les indicateurs multilignes, point-all, collants ou Unicode, donc les exemples nécessitant `m`, `s`, `y`, `u` ou `v` nécessitent une adaptation et certains ne peuvent pas y être reproduits. Utilisez l'outil pour tester les modèles JavaScript pris en charge, lire le nombre de remplacements et annuler avant d'affiner.